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 <glebius@FreeBSD.org>
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 #include "opt_inet.h"
42 #include "opt_inet6.h"
43 #include "opt_bpf.h"
44 #include "opt_pf.h"
45
46 #include <sys/param.h>
47 #include <sys/_bitset.h>
48 #include <sys/bitset.h>
49 #include <sys/bus.h>
50 #include <sys/conf.h>
51 #include <sys/endian.h>
52 #include <sys/fcntl.h>
53 #include <sys/filio.h>
54 #include <sys/hash.h>
55 #include <sys/interrupt.h>
56 #include <sys/jail.h>
57 #include <sys/kernel.h>
58 #include <sys/kthread.h>
59 #include <sys/lock.h>
60 #include <sys/mbuf.h>
61 #include <sys/module.h>
62 #include <sys/nv.h>
63 #include <sys/proc.h>
64 #include <sys/sdt.h>
65 #include <sys/smp.h>
66 #include <sys/socket.h>
67 #include <sys/sysctl.h>
68 #include <sys/md5.h>
69 #include <sys/ucred.h>
70
71 #include <net/if.h>
72 #include <net/if_var.h>
73 #include <net/if_private.h>
74 #include <net/vnet.h>
75 #include <net/route.h>
76 #include <net/pfil.h>
77 #include <net/pfvar.h>
78 #include <net/if_pfsync.h>
79 #include <net/if_pflog.h>
80
81 #include <netinet/in.h>
82 #include <netinet/ip.h>
83 #include <netinet/ip_var.h>
84 #include <netinet6/ip6_var.h>
85 #include <netinet/ip_icmp.h>
86 #include <netpfil/pf/pf_nl.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_PROBE_DEFINE3(pf, ioctl, ioctl, error, "int", "int", "int");
98 SDT_PROBE_DEFINE3(pf, ioctl, function, error, "char *", "int", "int");
99 SDT_PROBE_DEFINE2(pf, ioctl, addrule, error, "int", "int");
100 SDT_PROBE_DEFINE2(pf, ioctl, nvchk, error, "int", "int");
101
102 static struct pf_kpool *pf_get_kpool(const char *, u_int32_t, u_int8_t,
103 u_int32_t, u_int8_t, u_int8_t, u_int8_t, int);
104
105 static void pf_mv_kpool(struct pf_kpalist *, struct pf_kpalist *);
106 static void pf_empty_kpool(struct pf_kpalist *);
107 static int pfioctl(struct cdev *, u_long, caddr_t, int,
108 struct thread *);
109 static int pf_begin_eth(uint32_t *, const char *);
110 static int pf_rollback_eth(uint32_t, const char *);
111 static int pf_commit_eth(uint32_t, const char *);
112 static void pf_free_eth_rule(struct pf_keth_rule *);
113 #ifdef ALTQ
114 static int pf_begin_altq(u_int32_t *);
115 static int pf_rollback_altq(u_int32_t);
116 static int pf_commit_altq(u_int32_t);
117 static int pf_enable_altq(struct pf_altq *);
118 static int pf_disable_altq(struct pf_altq *);
119 static void pf_qid_unref(uint16_t);
120 #endif /* ALTQ */
121 static int pf_begin_rules(u_int32_t *, int, const char *);
122 static int pf_rollback_rules(u_int32_t, int, char *);
123 static int pf_setup_pfsync_matching(struct pf_kruleset *);
124 static void pf_hash_rule_rolling(MD5_CTX *, struct pf_krule *);
125 static void pf_hash_rule(struct pf_krule *);
126 static void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
127 static int pf_commit_rules(u_int32_t, int, char *);
128 static int pf_addr_setup(struct pf_kruleset *,
129 struct pf_addr_wrap *, sa_family_t);
130 static void pf_src_node_copy(const struct pf_ksrc_node *,
131 struct pf_src_node *);
132 #ifdef ALTQ
133 static int pf_export_kaltq(struct pf_altq *,
134 struct pfioc_altq_v1 *, size_t);
135 static int pf_import_kaltq(struct pfioc_altq_v1 *,
136 struct pf_altq *, size_t);
137 #endif /* ALTQ */
138
139 VNET_DEFINE(struct pf_krule, pf_default_rule);
140
141 static __inline int pf_krule_compare(struct pf_krule *,
142 struct pf_krule *);
143
144 RB_GENERATE(pf_krule_global, pf_krule, entry_global, pf_krule_compare);
145
146 #ifdef ALTQ
147 VNET_DEFINE_STATIC(int, pf_altq_running);
148 #define V_pf_altq_running VNET(pf_altq_running)
149 #endif
150
151 #define TAGID_MAX 50000
152 struct pf_tagname {
153 TAILQ_ENTRY(pf_tagname) namehash_entries;
154 TAILQ_ENTRY(pf_tagname) taghash_entries;
155 char name[PF_TAG_NAME_SIZE];
156 uint16_t tag;
157 int ref;
158 };
159
160 struct pf_tagset {
161 TAILQ_HEAD(, pf_tagname) *namehash;
162 TAILQ_HEAD(, pf_tagname) *taghash;
163 unsigned int mask;
164 uint32_t seed;
165 BITSET_DEFINE(, TAGID_MAX) avail;
166 };
167
168 VNET_DEFINE(struct pf_tagset, pf_tags);
169 #define V_pf_tags VNET(pf_tags)
170 static unsigned int pf_rule_tag_hashsize;
171 #define PF_RULE_TAG_HASH_SIZE_DEFAULT 128
172 SYSCTL_UINT(_net_pf, OID_AUTO, rule_tag_hashsize, CTLFLAG_RDTUN,
173 &pf_rule_tag_hashsize, PF_RULE_TAG_HASH_SIZE_DEFAULT,
174 "Size of pf(4) rule tag hashtable");
175
176 #ifdef ALTQ
177 VNET_DEFINE(struct pf_tagset, pf_qids);
178 #define V_pf_qids VNET(pf_qids)
179 static unsigned int pf_queue_tag_hashsize;
180 #define PF_QUEUE_TAG_HASH_SIZE_DEFAULT 128
181 SYSCTL_UINT(_net_pf, OID_AUTO, queue_tag_hashsize, CTLFLAG_RDTUN,
182 &pf_queue_tag_hashsize, PF_QUEUE_TAG_HASH_SIZE_DEFAULT,
183 "Size of pf(4) queue tag hashtable");
184 #endif
185 VNET_DEFINE(uma_zone_t, pf_tag_z);
186 #define V_pf_tag_z VNET(pf_tag_z)
187 static MALLOC_DEFINE(M_PFALTQ, "pf_altq", "pf(4) altq configuration db");
188 static MALLOC_DEFINE(M_PFRULE, "pf_rule", "pf(4) rules");
189 MALLOC_DEFINE(M_PF, "pf", "pf(4)");
190
191 #if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
192 #error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
193 #endif
194
195 VNET_DEFINE_STATIC(bool, pf_filter_local) = false;
196 #define V_pf_filter_local VNET(pf_filter_local)
197 SYSCTL_BOOL(_net_pf, OID_AUTO, filter_local, CTLFLAG_VNET | CTLFLAG_RW,
198 &VNET_NAME(pf_filter_local), false,
199 "Enable filtering for packets delivered to local network stack");
200
201 #ifdef PF_DEFAULT_TO_DROP
202 VNET_DEFINE_STATIC(bool, default_to_drop) = true;
203 #else
204 VNET_DEFINE_STATIC(bool, default_to_drop);
205 #endif
206 #define V_default_to_drop VNET(default_to_drop)
207 SYSCTL_BOOL(_net_pf, OID_AUTO, default_to_drop, CTLFLAG_RDTUN | CTLFLAG_VNET,
208 &VNET_NAME(default_to_drop), false,
209 "Make the default rule drop all packets.");
210
211 static void pf_init_tagset(struct pf_tagset *, unsigned int *,
212 unsigned int);
213 static void pf_cleanup_tagset(struct pf_tagset *);
214 static uint16_t tagname2hashindex(const struct pf_tagset *, const char *);
215 static uint16_t tag2hashindex(const struct pf_tagset *, uint16_t);
216 static u_int16_t tagname2tag(struct pf_tagset *, const char *, bool);
217 static void tag_unref(struct pf_tagset *, u_int16_t);
218
219 struct cdev *pf_dev;
220
221 /*
222 * XXX - These are new and need to be checked when moveing to a new version
223 */
224 static void pf_clear_all_states(void);
225 static int pf_killstates_row(struct pf_kstate_kill *,
226 struct pf_idhash *);
227 static int pf_killstates_nv(struct pfioc_nv *);
228 static int pf_clearstates_nv(struct pfioc_nv *);
229 static int pf_getstate(struct pfioc_nv *);
230 static int pf_getstatus(struct pfioc_nv *);
231 static int pf_clear_tables(void);
232 static void pf_kill_srcnodes(struct pfioc_src_node_kill *);
233 static int pf_keepcounters(struct pfioc_nv *);
234 static void pf_tbladdr_copyout(struct pf_addr_wrap *);
235
236 /*
237 * Wrapper functions for pfil(9) hooks
238 */
239 static pfil_return_t pf_eth_check_in(struct mbuf **m, struct ifnet *ifp,
240 int flags, void *ruleset __unused, struct inpcb *inp);
241 static pfil_return_t pf_eth_check_out(struct mbuf **m, struct ifnet *ifp,
242 int flags, void *ruleset __unused, struct inpcb *inp);
243 #ifdef INET
244 static pfil_return_t pf_check_in(struct mbuf **m, struct ifnet *ifp,
245 int flags, void *ruleset __unused, struct inpcb *inp);
246 static pfil_return_t pf_check_out(struct mbuf **m, struct ifnet *ifp,
247 int flags, void *ruleset __unused, struct inpcb *inp);
248 #endif
249 #ifdef INET6
250 static pfil_return_t pf_check6_in(struct mbuf **m, struct ifnet *ifp,
251 int flags, void *ruleset __unused, struct inpcb *inp);
252 static pfil_return_t pf_check6_out(struct mbuf **m, struct ifnet *ifp,
253 int flags, void *ruleset __unused, struct inpcb *inp);
254 #endif
255
256 static void hook_pf_eth(void);
257 static void hook_pf(void);
258 static void dehook_pf_eth(void);
259 static void dehook_pf(void);
260 static int shutdown_pf(void);
261 static int pf_load(void);
262 static void pf_unload(void *);
263
264 static struct cdevsw pf_cdevsw = {
265 .d_ioctl = pfioctl,
266 .d_name = PF_NAME,
267 .d_version = D_VERSION,
268 };
269
270 VNET_DEFINE_STATIC(bool, pf_pfil_hooked);
271 #define V_pf_pfil_hooked VNET(pf_pfil_hooked)
272 VNET_DEFINE_STATIC(bool, pf_pfil_eth_hooked);
273 #define V_pf_pfil_eth_hooked VNET(pf_pfil_eth_hooked)
274
275 /*
276 * We need a flag that is neither hooked nor running to know when
277 * the VNET is "valid". We primarily need this to control (global)
278 * external event, e.g., eventhandlers.
279 */
280 VNET_DEFINE(int, pf_vnet_active);
281 #define V_pf_vnet_active VNET(pf_vnet_active)
282
283 int pf_end_threads;
284 struct proc *pf_purge_proc;
285
286 VNET_DEFINE(struct rmlock, pf_rules_lock);
287 VNET_DEFINE(struct rmlock, pf_tags_lock);
288 VNET_DEFINE_STATIC(struct sx, pf_ioctl_lock);
289 #define V_pf_ioctl_lock VNET(pf_ioctl_lock)
290 struct sx pf_end_lock;
291
292 /* pfsync */
293 VNET_DEFINE(pfsync_state_import_t *, pfsync_state_import_ptr);
294 VNET_DEFINE(pfsync_insert_state_t *, pfsync_insert_state_ptr);
295 VNET_DEFINE(pfsync_update_state_t *, pfsync_update_state_ptr);
296 VNET_DEFINE(pfsync_delete_state_t *, pfsync_delete_state_ptr);
297 VNET_DEFINE(pfsync_clear_states_t *, pfsync_clear_states_ptr);
298 VNET_DEFINE(pfsync_defer_t *, pfsync_defer_ptr);
299 VNET_DEFINE(pflow_export_state_t *, pflow_export_state_ptr);
300 pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
301
302 /* pflog */
303 pflog_packet_t *pflog_packet_ptr = NULL;
304
305 /*
306 * Copy a user-provided string, returning an error if truncation would occur.
307 * Avoid scanning past "sz" bytes in the source string since there's no
308 * guarantee that it's nul-terminated.
309 */
310 static int
pf_user_strcpy(char * dst,const char * src,size_t sz)311 pf_user_strcpy(char *dst, const char *src, size_t sz)
312 {
313 if (strnlen(src, sz) == sz)
314 return (EINVAL);
315 (void)strlcpy(dst, src, sz);
316 return (0);
317 }
318
319 static void
pfattach_vnet(void)320 pfattach_vnet(void)
321 {
322 u_int32_t *my_timeout = V_pf_default_rule.timeout;
323
324 bzero(&V_pf_status, sizeof(V_pf_status));
325
326 pf_initialize();
327 pfr_initialize();
328 pfi_initialize_vnet();
329 pf_normalize_init();
330 pf_syncookies_init();
331
332 V_pf_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
333 V_pf_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
334 V_pf_limits[PF_LIMIT_ANCHORS].limit = PF_ANCHOR_HIWAT;
335 V_pf_limits[PF_LIMIT_ETH_ANCHORS].limit = PF_ANCHOR_HIWAT;
336
337 RB_INIT(&V_pf_anchors);
338 pf_init_kruleset(&pf_main_ruleset);
339
340 pf_init_keth(V_pf_keth);
341
342 /* default rule should never be garbage collected */
343 V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next;
344 V_pf_default_rule.action = V_default_to_drop ? PF_DROP : PF_PASS;
345 V_pf_default_rule.nr = (uint32_t)-1;
346 V_pf_default_rule.rtableid = -1;
347
348 pf_counter_u64_init(&V_pf_default_rule.evaluations, M_WAITOK);
349 for (int i = 0; i < 2; i++) {
350 pf_counter_u64_init(&V_pf_default_rule.packets[i], M_WAITOK);
351 pf_counter_u64_init(&V_pf_default_rule.bytes[i], M_WAITOK);
352 }
353 V_pf_default_rule.states_cur = counter_u64_alloc(M_WAITOK);
354 V_pf_default_rule.states_tot = counter_u64_alloc(M_WAITOK);
355 for (pf_sn_types_t sn_type = 0; sn_type<PF_SN_MAX; sn_type++)
356 V_pf_default_rule.src_nodes[sn_type] = counter_u64_alloc(M_WAITOK);
357
358 V_pf_default_rule.timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
359 M_WAITOK | M_ZERO);
360
361 #ifdef PF_WANT_32_TO_64_COUNTER
362 V_pf_kifmarker = malloc(sizeof(*V_pf_kifmarker), PFI_MTYPE, M_WAITOK | M_ZERO);
363 V_pf_rulemarker = malloc(sizeof(*V_pf_rulemarker), M_PFRULE, M_WAITOK | M_ZERO);
364 PF_RULES_WLOCK();
365 LIST_INSERT_HEAD(&V_pf_allkiflist, V_pf_kifmarker, pfik_allkiflist);
366 LIST_INSERT_HEAD(&V_pf_allrulelist, &V_pf_default_rule, allrulelist);
367 V_pf_allrulecount++;
368 LIST_INSERT_HEAD(&V_pf_allrulelist, V_pf_rulemarker, allrulelist);
369 PF_RULES_WUNLOCK();
370 #endif
371
372 /* initialize default timeouts */
373 my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
374 my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
375 my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
376 my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
377 my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
378 my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
379 my_timeout[PFTM_SCTP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
380 my_timeout[PFTM_SCTP_OPENING] = PFTM_TCP_OPENING_VAL;
381 my_timeout[PFTM_SCTP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
382 my_timeout[PFTM_SCTP_CLOSING] = PFTM_TCP_CLOSING_VAL;
383 my_timeout[PFTM_SCTP_CLOSED] = PFTM_TCP_CLOSED_VAL;
384 my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
385 my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
386 my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
387 my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
388 my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
389 my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
390 my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
391 my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
392 my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
393 my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
394 my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
395 my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
396 my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
397 my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
398
399 V_pf_status.debug = PF_DEBUG_URGENT;
400 /*
401 * XXX This is different than in OpenBSD where reassembly is enabled by
402 * defult. In FreeBSD we expect people to still use scrub rules and
403 * switch to the new syntax later. Only when they switch they must
404 * explicitly enable reassemle. We could change the default once the
405 * scrub rule functionality is hopefully removed some day in future.
406 */
407 V_pf_status.reass = 0;
408
409 V_pf_pfil_hooked = false;
410 V_pf_pfil_eth_hooked = false;
411
412 /* XXX do our best to avoid a conflict */
413 V_pf_status.hostid = arc4random();
414
415 for (int i = 0; i < PFRES_MAX; i++)
416 V_pf_status.counters[i] = counter_u64_alloc(M_WAITOK);
417 for (int i = 0; i < KLCNT_MAX; i++)
418 V_pf_status.lcounters[i] = counter_u64_alloc(M_WAITOK);
419 for (int i = 0; i < FCNT_MAX; i++)
420 pf_counter_u64_init(&V_pf_status.fcounters[i], M_WAITOK);
421 for (int i = 0; i < SCNT_MAX; i++)
422 V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK);
423 for (int i = 0; i < NCNT_MAX; i++)
424 V_pf_status.ncounters[i] = counter_u64_alloc(M_WAITOK);
425
426 if (swi_add(&V_pf_swi_ie, "pf send", pf_intr, curvnet, SWI_NET,
427 INTR_MPSAFE, &V_pf_swi_cookie) != 0)
428 /* XXXGL: leaked all above. */
429 return;
430 }
431
432 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,int which)433 pf_get_kpool(const char *anchor, u_int32_t ticket, u_int8_t rule_action,
434 u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
435 u_int8_t check_ticket, int which)
436 {
437 struct pf_kruleset *ruleset;
438 struct pf_krule *rule;
439 int rs_num;
440
441 MPASS(which == PF_RDR || which == PF_NAT || which == PF_RT);
442
443 ruleset = pf_find_kruleset(anchor);
444 if (ruleset == NULL)
445 return (NULL);
446 rs_num = pf_get_ruleset_number(rule_action);
447 if (rs_num >= PF_RULESET_MAX)
448 return (NULL);
449 if (active) {
450 if (check_ticket && ticket !=
451 ruleset->rules[rs_num].active.ticket)
452 return (NULL);
453 if (r_last)
454 rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
455 pf_krulequeue);
456 else
457 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
458 } else {
459 if (check_ticket && ticket !=
460 ruleset->rules[rs_num].inactive.ticket)
461 return (NULL);
462 if (r_last)
463 rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
464 pf_krulequeue);
465 else
466 rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
467 }
468 if (!r_last) {
469 while ((rule != NULL) && (rule->nr != rule_number))
470 rule = TAILQ_NEXT(rule, entries);
471 }
472 if (rule == NULL)
473 return (NULL);
474
475 switch (which) {
476 case PF_RDR:
477 return (&rule->rdr);
478 case PF_NAT:
479 return (&rule->nat);
480 case PF_RT:
481 return (&rule->route);
482 default:
483 panic("Unknow pool type %d", which);
484 }
485 }
486
487 static void
pf_mv_kpool(struct pf_kpalist * poola,struct pf_kpalist * poolb)488 pf_mv_kpool(struct pf_kpalist *poola, struct pf_kpalist *poolb)
489 {
490 struct pf_kpooladdr *mv_pool_pa;
491
492 while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
493 TAILQ_REMOVE(poola, mv_pool_pa, entries);
494 TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
495 }
496 }
497
498 static void
pf_empty_kpool(struct pf_kpalist * poola)499 pf_empty_kpool(struct pf_kpalist *poola)
500 {
501 struct pf_kpooladdr *pa;
502
503 while ((pa = TAILQ_FIRST(poola)) != NULL) {
504 switch (pa->addr.type) {
505 case PF_ADDR_DYNIFTL:
506 pfi_dynaddr_remove(pa->addr.p.dyn);
507 break;
508 case PF_ADDR_TABLE:
509 /* XXX: this could be unfinished pooladdr on pabuf */
510 if (pa->addr.p.tbl != NULL)
511 pfr_detach_table(pa->addr.p.tbl);
512 break;
513 }
514 if (pa->kif)
515 pfi_kkif_unref(pa->kif);
516 TAILQ_REMOVE(poola, pa, entries);
517 free(pa, M_PFRULE);
518 }
519 }
520
521 static void
pf_unlink_rule_locked(struct pf_krulequeue * rulequeue,struct pf_krule * rule)522 pf_unlink_rule_locked(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
523 {
524
525 PF_RULES_WASSERT();
526 PF_UNLNKDRULES_ASSERT();
527
528 TAILQ_REMOVE(rulequeue, rule, entries);
529
530 rule->rule_ref |= PFRULE_REFS;
531 TAILQ_INSERT_TAIL(&V_pf_unlinked_rules, rule, entries);
532 }
533
534 static void
pf_unlink_rule(struct pf_krulequeue * rulequeue,struct pf_krule * rule)535 pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
536 {
537
538 PF_RULES_WASSERT();
539
540 PF_UNLNKDRULES_LOCK();
541 pf_unlink_rule_locked(rulequeue, rule);
542 PF_UNLNKDRULES_UNLOCK();
543 }
544
545 static void
pf_free_eth_rule(struct pf_keth_rule * rule)546 pf_free_eth_rule(struct pf_keth_rule *rule)
547 {
548 PF_RULES_WASSERT();
549
550 if (rule == NULL)
551 return;
552
553 if (rule->tag)
554 tag_unref(&V_pf_tags, rule->tag);
555 if (rule->match_tag)
556 tag_unref(&V_pf_tags, rule->match_tag);
557 #ifdef ALTQ
558 pf_qid_unref(rule->qid);
559 #endif
560
561 if (rule->bridge_to)
562 pfi_kkif_unref(rule->bridge_to);
563 if (rule->kif)
564 pfi_kkif_unref(rule->kif);
565
566 if (rule->ipsrc.addr.type == PF_ADDR_TABLE)
567 pfr_detach_table(rule->ipsrc.addr.p.tbl);
568 if (rule->ipdst.addr.type == PF_ADDR_TABLE)
569 pfr_detach_table(rule->ipdst.addr.p.tbl);
570
571 counter_u64_free(rule->evaluations);
572 for (int i = 0; i < 2; i++) {
573 counter_u64_free(rule->packets[i]);
574 counter_u64_free(rule->bytes[i]);
575 }
576 uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp);
577 pf_keth_anchor_remove(rule);
578
579 free(rule, M_PFRULE);
580 }
581
582 void
pf_free_rule(struct pf_krule * rule)583 pf_free_rule(struct pf_krule *rule)
584 {
585
586 PF_RULES_WASSERT();
587 PF_CONFIG_ASSERT();
588
589 if (rule->tag)
590 tag_unref(&V_pf_tags, rule->tag);
591 if (rule->match_tag)
592 tag_unref(&V_pf_tags, rule->match_tag);
593 #ifdef ALTQ
594 if (rule->pqid != rule->qid)
595 pf_qid_unref(rule->pqid);
596 pf_qid_unref(rule->qid);
597 #endif
598 switch (rule->src.addr.type) {
599 case PF_ADDR_DYNIFTL:
600 pfi_dynaddr_remove(rule->src.addr.p.dyn);
601 break;
602 case PF_ADDR_TABLE:
603 pfr_detach_table(rule->src.addr.p.tbl);
604 break;
605 }
606 switch (rule->dst.addr.type) {
607 case PF_ADDR_DYNIFTL:
608 pfi_dynaddr_remove(rule->dst.addr.p.dyn);
609 break;
610 case PF_ADDR_TABLE:
611 pfr_detach_table(rule->dst.addr.p.tbl);
612 break;
613 }
614 if (rule->overload_tbl)
615 pfr_detach_table(rule->overload_tbl);
616 if (rule->kif)
617 pfi_kkif_unref(rule->kif);
618 if (rule->rcv_kif)
619 pfi_kkif_unref(rule->rcv_kif);
620 pf_remove_kanchor(rule);
621 pf_empty_kpool(&rule->rdr.list);
622 pf_empty_kpool(&rule->nat.list);
623 pf_empty_kpool(&rule->route.list);
624
625 pf_krule_free(rule);
626 }
627
628 static void
pf_init_tagset(struct pf_tagset * ts,unsigned int * tunable_size,unsigned int default_size)629 pf_init_tagset(struct pf_tagset *ts, unsigned int *tunable_size,
630 unsigned int default_size)
631 {
632 unsigned int i;
633 unsigned int hashsize;
634
635 if (*tunable_size == 0 || !powerof2(*tunable_size))
636 *tunable_size = default_size;
637
638 hashsize = *tunable_size;
639 ts->namehash = mallocarray(hashsize, sizeof(*ts->namehash), M_PFHASH,
640 M_WAITOK);
641 ts->taghash = mallocarray(hashsize, sizeof(*ts->taghash), M_PFHASH,
642 M_WAITOK);
643 ts->mask = hashsize - 1;
644 ts->seed = arc4random();
645 for (i = 0; i < hashsize; i++) {
646 TAILQ_INIT(&ts->namehash[i]);
647 TAILQ_INIT(&ts->taghash[i]);
648 }
649 BIT_FILL(TAGID_MAX, &ts->avail);
650 }
651
652 static void
pf_cleanup_tagset(struct pf_tagset * ts)653 pf_cleanup_tagset(struct pf_tagset *ts)
654 {
655 unsigned int i;
656 unsigned int hashsize;
657 struct pf_tagname *t, *tmp;
658
659 /*
660 * Only need to clean up one of the hashes as each tag is hashed
661 * into each table.
662 */
663 hashsize = ts->mask + 1;
664 for (i = 0; i < hashsize; i++)
665 TAILQ_FOREACH_SAFE(t, &ts->namehash[i], namehash_entries, tmp)
666 uma_zfree(V_pf_tag_z, t);
667
668 free(ts->namehash, M_PFHASH);
669 free(ts->taghash, M_PFHASH);
670 }
671
672 static uint16_t
tagname2hashindex(const struct pf_tagset * ts,const char * tagname)673 tagname2hashindex(const struct pf_tagset *ts, const char *tagname)
674 {
675 size_t len;
676
677 len = strnlen(tagname, PF_TAG_NAME_SIZE - 1);
678 return (murmur3_32_hash(tagname, len, ts->seed) & ts->mask);
679 }
680
681 static uint16_t
tag2hashindex(const struct pf_tagset * ts,uint16_t tag)682 tag2hashindex(const struct pf_tagset *ts, uint16_t tag)
683 {
684
685 return (tag & ts->mask);
686 }
687
688 static u_int16_t
tagname2tag(struct pf_tagset * ts,const char * tagname,bool add_new)689 tagname2tag(struct pf_tagset *ts, const char *tagname, bool add_new)
690 {
691 struct pf_tagname *tag;
692 u_int32_t index;
693 u_int16_t new_tagid;
694
695 PF_TAGS_RLOCK_TRACKER;
696
697 PF_TAGS_RLOCK();
698
699 index = tagname2hashindex(ts, tagname);
700 TAILQ_FOREACH(tag, &ts->namehash[index], namehash_entries)
701 if (strcmp(tagname, tag->name) == 0) {
702 tag->ref++;
703 new_tagid = tag->tag;
704 PF_TAGS_RUNLOCK();
705 return (new_tagid);
706 }
707
708 /*
709 * When used for pfsync with queues we must not create new entries.
710 * Pf tags can be created just fine by this function, but queues
711 * require additional configuration. If they are missing on the target
712 * system we just ignore them
713 */
714 if (add_new == false) {
715 printf("%s: Not creating a new tag\n", __func__);
716 PF_TAGS_RUNLOCK();
717 return (0);
718 }
719
720 /*
721 * If a new entry must be created do it under a write lock.
722 * But first search again, somebody could have created the tag
723 * between unlocking the read lock and locking the write lock.
724 */
725 PF_TAGS_RUNLOCK();
726 PF_TAGS_WLOCK();
727 TAILQ_FOREACH(tag, &ts->namehash[index], namehash_entries)
728 if (strcmp(tagname, tag->name) == 0) {
729 tag->ref++;
730 new_tagid = tag->tag;
731 PF_TAGS_WUNLOCK();
732 return (new_tagid);
733 }
734
735 /*
736 * new entry
737 *
738 * to avoid fragmentation, we do a linear search from the beginning
739 * and take the first free slot we find.
740 */
741 new_tagid = BIT_FFS(TAGID_MAX, &ts->avail);
742 /*
743 * Tags are 1-based, with valid tags in the range [1..TAGID_MAX].
744 * BIT_FFS() returns a 1-based bit number, with 0 indicating no bits
745 * set. It may also return a bit number greater than TAGID_MAX due
746 * to rounding of the number of bits in the vector up to a multiple
747 * of the vector word size at declaration/allocation time.
748 */
749 if ((new_tagid == 0) || (new_tagid > TAGID_MAX)) {
750 PF_TAGS_WUNLOCK();
751 return (0);
752 }
753
754 /* Mark the tag as in use. Bits are 0-based for BIT_CLR() */
755 BIT_CLR(TAGID_MAX, new_tagid - 1, &ts->avail);
756
757 /* allocate and fill new struct pf_tagname */
758 tag = uma_zalloc(V_pf_tag_z, M_NOWAIT);
759 if (tag == NULL) {
760 PF_TAGS_WUNLOCK();
761 return (0);
762 }
763 strlcpy(tag->name, tagname, sizeof(tag->name));
764 tag->tag = new_tagid;
765 tag->ref = 1;
766
767 /* Insert into namehash */
768 TAILQ_INSERT_TAIL(&ts->namehash[index], tag, namehash_entries);
769
770 /* Insert into taghash */
771 index = tag2hashindex(ts, new_tagid);
772 TAILQ_INSERT_TAIL(&ts->taghash[index], tag, taghash_entries);
773
774 PF_TAGS_WUNLOCK();
775 return (new_tagid);
776 }
777
778 static char *
tag2tagname(struct pf_tagset * ts,u_int16_t tag)779 tag2tagname(struct pf_tagset *ts, u_int16_t tag)
780 {
781 struct pf_tagname *t;
782 uint16_t index;
783
784 PF_TAGS_RLOCK_TRACKER;
785
786 PF_TAGS_RLOCK();
787
788 index = tag2hashindex(ts, tag);
789 TAILQ_FOREACH(t, &ts->taghash[index], taghash_entries)
790 if (tag == t->tag) {
791 PF_TAGS_RUNLOCK();
792 return (t->name);
793 }
794
795 PF_TAGS_RUNLOCK();
796 return (NULL);
797 }
798
799 static void
tag_unref(struct pf_tagset * ts,u_int16_t tag)800 tag_unref(struct pf_tagset *ts, u_int16_t tag)
801 {
802 struct pf_tagname *t;
803 uint16_t index;
804
805 PF_TAGS_WLOCK();
806
807 index = tag2hashindex(ts, tag);
808 TAILQ_FOREACH(t, &ts->taghash[index], taghash_entries)
809 if (tag == t->tag) {
810 if (--t->ref == 0) {
811 TAILQ_REMOVE(&ts->taghash[index], t,
812 taghash_entries);
813 index = tagname2hashindex(ts, t->name);
814 TAILQ_REMOVE(&ts->namehash[index], t,
815 namehash_entries);
816 /* Bits are 0-based for BIT_SET() */
817 BIT_SET(TAGID_MAX, tag - 1, &ts->avail);
818 uma_zfree(V_pf_tag_z, t);
819 }
820 break;
821 }
822
823 PF_TAGS_WUNLOCK();
824 }
825
826 uint16_t
pf_tagname2tag(const char * tagname)827 pf_tagname2tag(const char *tagname)
828 {
829 return (tagname2tag(&V_pf_tags, tagname, true));
830 }
831
832 static const char *
pf_tag2tagname(uint16_t tag)833 pf_tag2tagname(uint16_t tag)
834 {
835 return (tag2tagname(&V_pf_tags, tag));
836 }
837
838 static int
pf_begin_eth(uint32_t * ticket,const char * anchor)839 pf_begin_eth(uint32_t *ticket, const char *anchor)
840 {
841 struct pf_keth_rule *rule, *tmp;
842 struct pf_keth_ruleset *rs;
843
844 PF_RULES_WASSERT();
845
846 rs = pf_find_or_create_keth_ruleset(anchor);
847 if (rs == NULL)
848 return (EINVAL);
849
850 /* Purge old inactive rules. */
851 TAILQ_FOREACH_SAFE(rule, rs->inactive.rules, entries,
852 tmp) {
853 TAILQ_REMOVE(rs->inactive.rules, rule,
854 entries);
855 pf_free_eth_rule(rule);
856 }
857
858 *ticket = ++rs->inactive.ticket;
859 rs->inactive.open = 1;
860
861 return (0);
862 }
863
864 static int
pf_rollback_eth(uint32_t ticket,const char * anchor)865 pf_rollback_eth(uint32_t ticket, const char *anchor)
866 {
867 struct pf_keth_rule *rule, *tmp;
868 struct pf_keth_ruleset *rs;
869
870 PF_RULES_WASSERT();
871
872 rs = pf_find_keth_ruleset(anchor);
873 if (rs == NULL)
874 return (EINVAL);
875
876 if (!rs->inactive.open ||
877 ticket != rs->inactive.ticket)
878 return (0);
879
880 /* Purge old inactive rules. */
881 TAILQ_FOREACH_SAFE(rule, rs->inactive.rules, entries,
882 tmp) {
883 TAILQ_REMOVE(rs->inactive.rules, rule, entries);
884 pf_free_eth_rule(rule);
885 }
886
887 rs->inactive.open = 0;
888
889 pf_remove_if_empty_keth_ruleset(rs);
890
891 return (0);
892 }
893
894 #define PF_SET_SKIP_STEPS(i) \
895 do { \
896 while (head[i] != cur) { \
897 head[i]->skip[i].ptr = cur; \
898 head[i] = TAILQ_NEXT(head[i], entries); \
899 } \
900 } while (0)
901
902 static void
pf_eth_calc_skip_steps(struct pf_keth_ruleq * rules)903 pf_eth_calc_skip_steps(struct pf_keth_ruleq *rules)
904 {
905 struct pf_keth_rule *cur, *prev, *head[PFE_SKIP_COUNT];
906 int i;
907
908 cur = TAILQ_FIRST(rules);
909 prev = cur;
910 for (i = 0; i < PFE_SKIP_COUNT; ++i)
911 head[i] = cur;
912 while (cur != NULL) {
913 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
914 PF_SET_SKIP_STEPS(PFE_SKIP_IFP);
915 if (cur->direction != prev->direction)
916 PF_SET_SKIP_STEPS(PFE_SKIP_DIR);
917 if (cur->proto != prev->proto)
918 PF_SET_SKIP_STEPS(PFE_SKIP_PROTO);
919 if (memcmp(&cur->src, &prev->src, sizeof(cur->src)) != 0)
920 PF_SET_SKIP_STEPS(PFE_SKIP_SRC_ADDR);
921 if (memcmp(&cur->dst, &prev->dst, sizeof(cur->dst)) != 0)
922 PF_SET_SKIP_STEPS(PFE_SKIP_DST_ADDR);
923 if (cur->ipsrc.neg != prev->ipsrc.neg ||
924 pf_addr_wrap_neq(&cur->ipsrc.addr, &prev->ipsrc.addr))
925 PF_SET_SKIP_STEPS(PFE_SKIP_SRC_IP_ADDR);
926 if (cur->ipdst.neg != prev->ipdst.neg ||
927 pf_addr_wrap_neq(&cur->ipdst.addr, &prev->ipdst.addr))
928 PF_SET_SKIP_STEPS(PFE_SKIP_DST_IP_ADDR);
929
930 prev = cur;
931 cur = TAILQ_NEXT(cur, entries);
932 }
933 for (i = 0; i < PFE_SKIP_COUNT; ++i)
934 PF_SET_SKIP_STEPS(i);
935 }
936
937 static int
pf_commit_eth(uint32_t ticket,const char * anchor)938 pf_commit_eth(uint32_t ticket, const char *anchor)
939 {
940 struct pf_keth_ruleq *rules;
941 struct pf_keth_ruleset *rs;
942
943 rs = pf_find_keth_ruleset(anchor);
944 if (rs == NULL) {
945 return (EINVAL);
946 }
947
948 if (!rs->inactive.open ||
949 ticket != rs->inactive.ticket)
950 return (EBUSY);
951
952 PF_RULES_WASSERT();
953
954 pf_eth_calc_skip_steps(rs->inactive.rules);
955
956 rules = rs->active.rules;
957 atomic_store_ptr(&rs->active.rules, rs->inactive.rules);
958 rs->inactive.rules = rules;
959 rs->inactive.ticket = rs->active.ticket;
960
961 return (pf_rollback_eth(rs->inactive.ticket,
962 rs->anchor ? rs->anchor->path : ""));
963 }
964
965 #ifdef ALTQ
966 uint16_t
pf_qname2qid(const char * qname,bool add_new)967 pf_qname2qid(const char *qname, bool add_new)
968 {
969 return (tagname2tag(&V_pf_qids, qname, add_new));
970 }
971
972 static const char *
pf_qid2qname(uint16_t qid)973 pf_qid2qname(uint16_t qid)
974 {
975 return (tag2tagname(&V_pf_qids, qid));
976 }
977
978 static void
pf_qid_unref(uint16_t qid)979 pf_qid_unref(uint16_t qid)
980 {
981 tag_unref(&V_pf_qids, qid);
982 }
983
984 static int
pf_begin_altq(u_int32_t * ticket)985 pf_begin_altq(u_int32_t *ticket)
986 {
987 struct pf_altq *altq, *tmp;
988 int error = 0;
989
990 PF_RULES_WASSERT();
991
992 /* Purge the old altq lists */
993 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
994 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
995 /* detach and destroy the discipline */
996 error = altq_remove(altq);
997 }
998 free(altq, M_PFALTQ);
999 }
1000 TAILQ_INIT(V_pf_altq_ifs_inactive);
1001 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
1002 pf_qid_unref(altq->qid);
1003 free(altq, M_PFALTQ);
1004 }
1005 TAILQ_INIT(V_pf_altqs_inactive);
1006 if (error)
1007 return (error);
1008 *ticket = ++V_ticket_altqs_inactive;
1009 V_altqs_inactive_open = 1;
1010 return (0);
1011 }
1012
1013 static int
pf_rollback_altq(u_int32_t ticket)1014 pf_rollback_altq(u_int32_t ticket)
1015 {
1016 struct pf_altq *altq, *tmp;
1017 int error = 0;
1018
1019 PF_RULES_WASSERT();
1020
1021 if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
1022 return (0);
1023 /* Purge the old altq lists */
1024 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
1025 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
1026 /* detach and destroy the discipline */
1027 error = altq_remove(altq);
1028 }
1029 free(altq, M_PFALTQ);
1030 }
1031 TAILQ_INIT(V_pf_altq_ifs_inactive);
1032 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
1033 pf_qid_unref(altq->qid);
1034 free(altq, M_PFALTQ);
1035 }
1036 TAILQ_INIT(V_pf_altqs_inactive);
1037 V_altqs_inactive_open = 0;
1038 return (error);
1039 }
1040
1041 static int
pf_commit_altq(u_int32_t ticket)1042 pf_commit_altq(u_int32_t ticket)
1043 {
1044 struct pf_altqqueue *old_altqs, *old_altq_ifs;
1045 struct pf_altq *altq, *tmp;
1046 int err, error = 0;
1047
1048 PF_RULES_WASSERT();
1049
1050 if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
1051 return (EBUSY);
1052
1053 /* swap altqs, keep the old. */
1054 old_altqs = V_pf_altqs_active;
1055 old_altq_ifs = V_pf_altq_ifs_active;
1056 V_pf_altqs_active = V_pf_altqs_inactive;
1057 V_pf_altq_ifs_active = V_pf_altq_ifs_inactive;
1058 V_pf_altqs_inactive = old_altqs;
1059 V_pf_altq_ifs_inactive = old_altq_ifs;
1060 V_ticket_altqs_active = V_ticket_altqs_inactive;
1061
1062 /* Attach new disciplines */
1063 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
1064 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
1065 /* attach the discipline */
1066 error = altq_pfattach(altq);
1067 if (error == 0 && V_pf_altq_running)
1068 error = pf_enable_altq(altq);
1069 if (error != 0)
1070 return (error);
1071 }
1072 }
1073
1074 /* Purge the old altq lists */
1075 TAILQ_FOREACH_SAFE(altq, V_pf_altq_ifs_inactive, entries, tmp) {
1076 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
1077 /* detach and destroy the discipline */
1078 if (V_pf_altq_running)
1079 error = pf_disable_altq(altq);
1080 err = altq_pfdetach(altq);
1081 if (err != 0 && error == 0)
1082 error = err;
1083 err = altq_remove(altq);
1084 if (err != 0 && error == 0)
1085 error = err;
1086 }
1087 free(altq, M_PFALTQ);
1088 }
1089 TAILQ_INIT(V_pf_altq_ifs_inactive);
1090 TAILQ_FOREACH_SAFE(altq, V_pf_altqs_inactive, entries, tmp) {
1091 pf_qid_unref(altq->qid);
1092 free(altq, M_PFALTQ);
1093 }
1094 TAILQ_INIT(V_pf_altqs_inactive);
1095
1096 V_altqs_inactive_open = 0;
1097 return (error);
1098 }
1099
1100 static int
pf_enable_altq(struct pf_altq * altq)1101 pf_enable_altq(struct pf_altq *altq)
1102 {
1103 struct ifnet *ifp;
1104 struct tb_profile tb;
1105 int error = 0;
1106
1107 if ((ifp = ifunit(altq->ifname)) == NULL)
1108 return (EINVAL);
1109
1110 if (ifp->if_snd.altq_type != ALTQT_NONE)
1111 error = altq_enable(&ifp->if_snd);
1112
1113 /* set tokenbucket regulator */
1114 if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
1115 tb.rate = altq->ifbandwidth;
1116 tb.depth = altq->tbrsize;
1117 error = tbr_set(&ifp->if_snd, &tb);
1118 }
1119
1120 return (error);
1121 }
1122
1123 static int
pf_disable_altq(struct pf_altq * altq)1124 pf_disable_altq(struct pf_altq *altq)
1125 {
1126 struct ifnet *ifp;
1127 struct tb_profile tb;
1128 int error;
1129
1130 if ((ifp = ifunit(altq->ifname)) == NULL)
1131 return (EINVAL);
1132
1133 /*
1134 * when the discipline is no longer referenced, it was overridden
1135 * by a new one. if so, just return.
1136 */
1137 if (altq->altq_disc != ifp->if_snd.altq_disc)
1138 return (0);
1139
1140 error = altq_disable(&ifp->if_snd);
1141
1142 if (error == 0) {
1143 /* clear tokenbucket regulator */
1144 tb.rate = 0;
1145 error = tbr_set(&ifp->if_snd, &tb);
1146 }
1147
1148 return (error);
1149 }
1150
1151 static int
pf_altq_ifnet_event_add(struct ifnet * ifp,int remove,u_int32_t ticket,struct pf_altq * altq)1152 pf_altq_ifnet_event_add(struct ifnet *ifp, int remove, u_int32_t ticket,
1153 struct pf_altq *altq)
1154 {
1155 struct ifnet *ifp1;
1156 int error = 0;
1157
1158 /* Deactivate the interface in question */
1159 altq->local_flags &= ~PFALTQ_FLAG_IF_REMOVED;
1160 if ((ifp1 = ifunit(altq->ifname)) == NULL ||
1161 (remove && ifp1 == ifp)) {
1162 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
1163 } else {
1164 error = altq_add(ifp1, altq);
1165
1166 if (ticket != V_ticket_altqs_inactive)
1167 error = EBUSY;
1168
1169 if (error)
1170 free(altq, M_PFALTQ);
1171 }
1172
1173 return (error);
1174 }
1175
1176 void
pf_altq_ifnet_event(struct ifnet * ifp,int remove)1177 pf_altq_ifnet_event(struct ifnet *ifp, int remove)
1178 {
1179 struct pf_altq *a1, *a2, *a3;
1180 u_int32_t ticket;
1181 int error = 0;
1182
1183 /*
1184 * No need to re-evaluate the configuration for events on interfaces
1185 * that do not support ALTQ, as it's not possible for such
1186 * interfaces to be part of the configuration.
1187 */
1188 if (!ALTQ_IS_READY(&ifp->if_snd))
1189 return;
1190
1191 /* Interrupt userland queue modifications */
1192 if (V_altqs_inactive_open)
1193 pf_rollback_altq(V_ticket_altqs_inactive);
1194
1195 /* Start new altq ruleset */
1196 if (pf_begin_altq(&ticket))
1197 return;
1198
1199 /* Copy the current active set */
1200 TAILQ_FOREACH(a1, V_pf_altq_ifs_active, entries) {
1201 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
1202 if (a2 == NULL) {
1203 error = ENOMEM;
1204 break;
1205 }
1206 bcopy(a1, a2, sizeof(struct pf_altq));
1207
1208 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
1209 if (error)
1210 break;
1211
1212 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, a2, entries);
1213 }
1214 if (error)
1215 goto out;
1216 TAILQ_FOREACH(a1, V_pf_altqs_active, entries) {
1217 a2 = malloc(sizeof(*a2), M_PFALTQ, M_NOWAIT);
1218 if (a2 == NULL) {
1219 error = ENOMEM;
1220 break;
1221 }
1222 bcopy(a1, a2, sizeof(struct pf_altq));
1223
1224 if ((a2->qid = pf_qname2qid(a2->qname, true)) == 0) {
1225 error = EBUSY;
1226 free(a2, M_PFALTQ);
1227 break;
1228 }
1229 a2->altq_disc = NULL;
1230 TAILQ_FOREACH(a3, V_pf_altq_ifs_inactive, entries) {
1231 if (strncmp(a3->ifname, a2->ifname,
1232 IFNAMSIZ) == 0) {
1233 a2->altq_disc = a3->altq_disc;
1234 break;
1235 }
1236 }
1237 error = pf_altq_ifnet_event_add(ifp, remove, ticket, a2);
1238 if (error)
1239 break;
1240
1241 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries);
1242 }
1243
1244 out:
1245 if (error != 0)
1246 pf_rollback_altq(ticket);
1247 else
1248 pf_commit_altq(ticket);
1249 }
1250 #endif /* ALTQ */
1251
1252 static struct pf_krule_global *
pf_rule_tree_alloc(int flags)1253 pf_rule_tree_alloc(int flags)
1254 {
1255 struct pf_krule_global *tree;
1256
1257 tree = malloc(sizeof(struct pf_krule_global), M_PF, flags);
1258 if (tree == NULL)
1259 return (NULL);
1260 RB_INIT(tree);
1261 return (tree);
1262 }
1263
1264 void
pf_rule_tree_free(struct pf_krule_global * tree)1265 pf_rule_tree_free(struct pf_krule_global *tree)
1266 {
1267
1268 free(tree, M_PF);
1269 }
1270
1271 static int
pf_begin_rules(u_int32_t * ticket,int rs_num,const char * anchor)1272 pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
1273 {
1274 struct pf_krule_global *tree;
1275 struct pf_kruleset *rs;
1276 struct pf_krule *rule;
1277
1278 PF_RULES_WASSERT();
1279
1280 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1281 return (EINVAL);
1282 tree = pf_rule_tree_alloc(M_NOWAIT);
1283 if (tree == NULL)
1284 return (ENOMEM);
1285 rs = pf_find_or_create_kruleset(anchor);
1286 if (rs == NULL) {
1287 pf_rule_tree_free(tree);
1288 return (EINVAL);
1289 }
1290 pf_rule_tree_free(rs->rules[rs_num].inactive.tree);
1291 rs->rules[rs_num].inactive.tree = tree;
1292
1293 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
1294 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
1295 rs->rules[rs_num].inactive.rcount--;
1296 }
1297 *ticket = ++rs->rules[rs_num].inactive.ticket;
1298 rs->rules[rs_num].inactive.open = 1;
1299 return (0);
1300 }
1301
1302 static int
pf_rollback_rules(u_int32_t ticket,int rs_num,char * anchor)1303 pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
1304 {
1305 struct pf_kruleset *rs;
1306 struct pf_krule *rule;
1307
1308 PF_RULES_WASSERT();
1309
1310 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1311 return (EINVAL);
1312 rs = pf_find_kruleset(anchor);
1313 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1314 rs->rules[rs_num].inactive.ticket != ticket)
1315 return (0);
1316 while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
1317 pf_unlink_rule(rs->rules[rs_num].inactive.ptr, rule);
1318 rs->rules[rs_num].inactive.rcount--;
1319 }
1320 rs->rules[rs_num].inactive.open = 0;
1321 return (0);
1322 }
1323
1324 #define PF_MD5_UPD(st, elm) \
1325 MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
1326
1327 #define PF_MD5_UPD_STR(st, elm) \
1328 MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm))
1329
1330 #define PF_MD5_UPD_HTONL(st, elm, stor) do { \
1331 (stor) = htonl((st)->elm); \
1332 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\
1333 } while (0)
1334
1335 #define PF_MD5_UPD_HTONS(st, elm, stor) do { \
1336 (stor) = htons((st)->elm); \
1337 MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\
1338 } while (0)
1339
1340 static void
pf_hash_rule_addr(MD5_CTX * ctx,struct pf_rule_addr * pfr)1341 pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
1342 {
1343 PF_MD5_UPD(pfr, addr.type);
1344 switch (pfr->addr.type) {
1345 case PF_ADDR_DYNIFTL:
1346 PF_MD5_UPD(pfr, addr.v.ifname);
1347 PF_MD5_UPD(pfr, addr.iflags);
1348 break;
1349 case PF_ADDR_TABLE:
1350 if (strncmp(pfr->addr.v.tblname, PF_OPTIMIZER_TABLE_PFX,
1351 strlen(PF_OPTIMIZER_TABLE_PFX)))
1352 PF_MD5_UPD(pfr, addr.v.tblname);
1353 break;
1354 case PF_ADDR_ADDRMASK:
1355 /* XXX ignore af? */
1356 PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
1357 PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
1358 break;
1359 }
1360
1361 PF_MD5_UPD(pfr, port[0]);
1362 PF_MD5_UPD(pfr, port[1]);
1363 PF_MD5_UPD(pfr, neg);
1364 PF_MD5_UPD(pfr, port_op);
1365 }
1366
1367 static void
pf_hash_rule_rolling(MD5_CTX * ctx,struct pf_krule * rule)1368 pf_hash_rule_rolling(MD5_CTX *ctx, struct pf_krule *rule)
1369 {
1370 u_int16_t x;
1371 u_int32_t y;
1372
1373 pf_hash_rule_addr(ctx, &rule->src);
1374 pf_hash_rule_addr(ctx, &rule->dst);
1375 for (int i = 0; i < PF_RULE_MAX_LABEL_COUNT; i++)
1376 PF_MD5_UPD_STR(rule, label[i]);
1377 PF_MD5_UPD_STR(rule, ifname);
1378 PF_MD5_UPD_STR(rule, rcv_ifname);
1379 PF_MD5_UPD_STR(rule, match_tagname);
1380 PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
1381 PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
1382 PF_MD5_UPD_HTONL(rule, prob, y);
1383 PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
1384 PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
1385 PF_MD5_UPD(rule, uid.op);
1386 PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
1387 PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
1388 PF_MD5_UPD(rule, gid.op);
1389 PF_MD5_UPD_HTONL(rule, rule_flag, y);
1390 PF_MD5_UPD(rule, action);
1391 PF_MD5_UPD(rule, direction);
1392 PF_MD5_UPD(rule, af);
1393 PF_MD5_UPD(rule, quick);
1394 PF_MD5_UPD(rule, ifnot);
1395 PF_MD5_UPD(rule, rcvifnot);
1396 PF_MD5_UPD(rule, match_tag_not);
1397 PF_MD5_UPD(rule, natpass);
1398 PF_MD5_UPD(rule, keep_state);
1399 PF_MD5_UPD(rule, proto);
1400 PF_MD5_UPD(rule, type);
1401 PF_MD5_UPD(rule, code);
1402 PF_MD5_UPD(rule, flags);
1403 PF_MD5_UPD(rule, flagset);
1404 PF_MD5_UPD(rule, allow_opts);
1405 PF_MD5_UPD(rule, rt);
1406 PF_MD5_UPD(rule, tos);
1407 PF_MD5_UPD(rule, scrub_flags);
1408 PF_MD5_UPD(rule, min_ttl);
1409 PF_MD5_UPD(rule, set_tos);
1410 if (rule->anchor != NULL)
1411 PF_MD5_UPD_STR(rule, anchor->path);
1412 }
1413
1414 static void
pf_hash_rule(struct pf_krule * rule)1415 pf_hash_rule(struct pf_krule *rule)
1416 {
1417 MD5_CTX ctx;
1418
1419 MD5Init(&ctx);
1420 pf_hash_rule_rolling(&ctx, rule);
1421 MD5Final(rule->md5sum, &ctx);
1422 }
1423
1424 static int
pf_krule_compare(struct pf_krule * a,struct pf_krule * b)1425 pf_krule_compare(struct pf_krule *a, struct pf_krule *b)
1426 {
1427
1428 return (memcmp(a->md5sum, b->md5sum, PF_MD5_DIGEST_LENGTH));
1429 }
1430
1431 static int
pf_commit_rules(u_int32_t ticket,int rs_num,char * anchor)1432 pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
1433 {
1434 struct pf_kruleset *rs;
1435 struct pf_krule *rule, *old_rule;
1436 struct pf_krulequeue *old_rules;
1437 struct pf_krule_global *old_tree;
1438 int error;
1439 u_int32_t old_rcount;
1440
1441 PF_RULES_WASSERT();
1442
1443 if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
1444 return (EINVAL);
1445 rs = pf_find_kruleset(anchor);
1446 if (rs == NULL || !rs->rules[rs_num].inactive.open ||
1447 ticket != rs->rules[rs_num].inactive.ticket)
1448 return (EBUSY);
1449
1450 /* Calculate checksum for the main ruleset */
1451 if (rs == &pf_main_ruleset) {
1452 error = pf_setup_pfsync_matching(rs);
1453 if (error != 0)
1454 return (error);
1455 }
1456
1457 /* Swap rules, keep the old. */
1458 old_rules = rs->rules[rs_num].active.ptr;
1459 old_rcount = rs->rules[rs_num].active.rcount;
1460 old_tree = rs->rules[rs_num].active.tree;
1461
1462 rs->rules[rs_num].active.ptr =
1463 rs->rules[rs_num].inactive.ptr;
1464 rs->rules[rs_num].active.tree =
1465 rs->rules[rs_num].inactive.tree;
1466 rs->rules[rs_num].active.rcount =
1467 rs->rules[rs_num].inactive.rcount;
1468
1469 /* Attempt to preserve counter information. */
1470 if (V_pf_status.keep_counters && old_tree != NULL) {
1471 TAILQ_FOREACH(rule, rs->rules[rs_num].active.ptr,
1472 entries) {
1473 old_rule = RB_FIND(pf_krule_global, old_tree, rule);
1474 if (old_rule == NULL) {
1475 continue;
1476 }
1477 pf_counter_u64_critical_enter();
1478 pf_counter_u64_rollup_protected(&rule->evaluations,
1479 pf_counter_u64_fetch(&old_rule->evaluations));
1480 pf_counter_u64_rollup_protected(&rule->packets[0],
1481 pf_counter_u64_fetch(&old_rule->packets[0]));
1482 pf_counter_u64_rollup_protected(&rule->packets[1],
1483 pf_counter_u64_fetch(&old_rule->packets[1]));
1484 pf_counter_u64_rollup_protected(&rule->bytes[0],
1485 pf_counter_u64_fetch(&old_rule->bytes[0]));
1486 pf_counter_u64_rollup_protected(&rule->bytes[1],
1487 pf_counter_u64_fetch(&old_rule->bytes[1]));
1488 pf_counter_u64_critical_exit();
1489 }
1490 }
1491
1492 rs->rules[rs_num].inactive.ptr = old_rules;
1493 rs->rules[rs_num].inactive.tree = NULL; /* important for pf_ioctl_addrule */
1494 rs->rules[rs_num].inactive.rcount = old_rcount;
1495
1496 rs->rules[rs_num].active.ticket =
1497 rs->rules[rs_num].inactive.ticket;
1498 pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
1499
1500 /* Purge the old rule list. */
1501 PF_UNLNKDRULES_LOCK();
1502 while ((rule = TAILQ_FIRST(old_rules)) != NULL)
1503 pf_unlink_rule_locked(old_rules, rule);
1504 PF_UNLNKDRULES_UNLOCK();
1505 rs->rules[rs_num].inactive.rcount = 0;
1506 rs->rules[rs_num].inactive.open = 0;
1507 pf_remove_if_empty_kruleset(rs);
1508 pf_rule_tree_free(old_tree);
1509
1510 return (0);
1511 }
1512
1513 static int
pf_setup_pfsync_matching(struct pf_kruleset * rs)1514 pf_setup_pfsync_matching(struct pf_kruleset *rs)
1515 {
1516 MD5_CTX ctx;
1517 struct pf_krule *rule;
1518 int rs_cnt;
1519 u_int8_t digest[PF_MD5_DIGEST_LENGTH];
1520
1521 MD5Init(&ctx);
1522 for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) {
1523 /* XXX PF_RULESET_SCRUB as well? */
1524 if (rs_cnt == PF_RULESET_SCRUB)
1525 continue;
1526
1527 if (rs->rules[rs_cnt].inactive.rcount) {
1528 TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
1529 entries) {
1530 pf_hash_rule_rolling(&ctx, rule);
1531 }
1532 }
1533 }
1534
1535 MD5Final(digest, &ctx);
1536 memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum));
1537 return (0);
1538 }
1539
1540 static int
pf_eth_addr_setup(struct pf_keth_ruleset * ruleset,struct pf_addr_wrap * addr)1541 pf_eth_addr_setup(struct pf_keth_ruleset *ruleset, struct pf_addr_wrap *addr)
1542 {
1543 int error = 0;
1544
1545 switch (addr->type) {
1546 case PF_ADDR_TABLE:
1547 addr->p.tbl = pfr_eth_attach_table(ruleset, addr->v.tblname);
1548 if (addr->p.tbl == NULL)
1549 error = ENOMEM;
1550 break;
1551 default:
1552 error = EINVAL;
1553 }
1554
1555 return (error);
1556 }
1557
1558 static int
pf_addr_setup(struct pf_kruleset * ruleset,struct pf_addr_wrap * addr,sa_family_t af)1559 pf_addr_setup(struct pf_kruleset *ruleset, struct pf_addr_wrap *addr,
1560 sa_family_t af)
1561 {
1562 int error = 0;
1563
1564 switch (addr->type) {
1565 case PF_ADDR_TABLE:
1566 addr->p.tbl = pfr_attach_table(ruleset, addr->v.tblname);
1567 if (addr->p.tbl == NULL)
1568 error = ENOMEM;
1569 break;
1570 case PF_ADDR_DYNIFTL:
1571 error = pfi_dynaddr_setup(addr, af);
1572 break;
1573 }
1574
1575 return (error);
1576 }
1577
1578 void
pf_addr_copyout(struct pf_addr_wrap * addr)1579 pf_addr_copyout(struct pf_addr_wrap *addr)
1580 {
1581
1582 switch (addr->type) {
1583 case PF_ADDR_DYNIFTL:
1584 pfi_dynaddr_copyout(addr);
1585 break;
1586 case PF_ADDR_TABLE:
1587 pf_tbladdr_copyout(addr);
1588 break;
1589 }
1590 }
1591
1592 static void
pf_src_node_copy(const struct pf_ksrc_node * in,struct pf_src_node * out)1593 pf_src_node_copy(const struct pf_ksrc_node *in, struct pf_src_node *out)
1594 {
1595 int secs = time_uptime;
1596
1597 bzero(out, sizeof(struct pf_src_node));
1598
1599 bcopy(&in->addr, &out->addr, sizeof(struct pf_addr));
1600 bcopy(&in->raddr, &out->raddr, sizeof(struct pf_addr));
1601
1602 if (in->rule != NULL)
1603 out->rule.nr = in->rule->nr;
1604
1605 for (int i = 0; i < 2; i++) {
1606 out->bytes[i] = counter_u64_fetch(in->bytes[i]);
1607 out->packets[i] = counter_u64_fetch(in->packets[i]);
1608 }
1609
1610 out->states = in->states;
1611 out->conn = in->conn;
1612 out->af = in->af;
1613 out->ruletype = in->ruletype;
1614
1615 out->creation = secs - in->creation;
1616 if (out->expire > secs)
1617 out->expire -= secs;
1618 else
1619 out->expire = 0;
1620
1621 /* Adjust the connection rate estimate. */
1622 out->conn_rate.limit = in->conn_rate.limit;
1623 out->conn_rate.seconds = in->conn_rate.seconds;
1624 /* If there's no limit there's no counter_rate. */
1625 if (in->conn_rate.cr != NULL)
1626 out->conn_rate.count = counter_rate_get(in->conn_rate.cr);
1627 }
1628
1629 #ifdef ALTQ
1630 /*
1631 * Handle export of struct pf_kaltq to user binaries that may be using any
1632 * version of struct pf_altq.
1633 */
1634 static int
pf_export_kaltq(struct pf_altq * q,struct pfioc_altq_v1 * pa,size_t ioc_size)1635 pf_export_kaltq(struct pf_altq *q, struct pfioc_altq_v1 *pa, size_t ioc_size)
1636 {
1637 u_int32_t version;
1638
1639 if (ioc_size == sizeof(struct pfioc_altq_v0))
1640 version = 0;
1641 else
1642 version = pa->version;
1643
1644 if (version > PFIOC_ALTQ_VERSION)
1645 return (EINVAL);
1646
1647 #define ASSIGN(x) exported_q->x = q->x
1648 #define COPY(x) \
1649 bcopy(&q->x, &exported_q->x, min(sizeof(q->x), sizeof(exported_q->x)))
1650 #define SATU16(x) (u_int32_t)uqmin((x), USHRT_MAX)
1651 #define SATU32(x) (u_int32_t)uqmin((x), UINT_MAX)
1652
1653 switch (version) {
1654 case 0: {
1655 struct pf_altq_v0 *exported_q =
1656 &((struct pfioc_altq_v0 *)pa)->altq;
1657
1658 COPY(ifname);
1659
1660 ASSIGN(scheduler);
1661 ASSIGN(tbrsize);
1662 exported_q->tbrsize = SATU16(q->tbrsize);
1663 exported_q->ifbandwidth = SATU32(q->ifbandwidth);
1664
1665 COPY(qname);
1666 COPY(parent);
1667 ASSIGN(parent_qid);
1668 exported_q->bandwidth = SATU32(q->bandwidth);
1669 ASSIGN(priority);
1670 ASSIGN(local_flags);
1671
1672 ASSIGN(qlimit);
1673 ASSIGN(flags);
1674
1675 if (q->scheduler == ALTQT_HFSC) {
1676 #define ASSIGN_OPT(x) exported_q->pq_u.hfsc_opts.x = q->pq_u.hfsc_opts.x
1677 #define ASSIGN_OPT_SATU32(x) exported_q->pq_u.hfsc_opts.x = \
1678 SATU32(q->pq_u.hfsc_opts.x)
1679
1680 ASSIGN_OPT_SATU32(rtsc_m1);
1681 ASSIGN_OPT(rtsc_d);
1682 ASSIGN_OPT_SATU32(rtsc_m2);
1683
1684 ASSIGN_OPT_SATU32(lssc_m1);
1685 ASSIGN_OPT(lssc_d);
1686 ASSIGN_OPT_SATU32(lssc_m2);
1687
1688 ASSIGN_OPT_SATU32(ulsc_m1);
1689 ASSIGN_OPT(ulsc_d);
1690 ASSIGN_OPT_SATU32(ulsc_m2);
1691
1692 ASSIGN_OPT(flags);
1693
1694 #undef ASSIGN_OPT
1695 #undef ASSIGN_OPT_SATU32
1696 } else
1697 COPY(pq_u);
1698
1699 ASSIGN(qid);
1700 break;
1701 }
1702 case 1: {
1703 struct pf_altq_v1 *exported_q =
1704 &((struct pfioc_altq_v1 *)pa)->altq;
1705
1706 COPY(ifname);
1707
1708 ASSIGN(scheduler);
1709 ASSIGN(tbrsize);
1710 ASSIGN(ifbandwidth);
1711
1712 COPY(qname);
1713 COPY(parent);
1714 ASSIGN(parent_qid);
1715 ASSIGN(bandwidth);
1716 ASSIGN(priority);
1717 ASSIGN(local_flags);
1718
1719 ASSIGN(qlimit);
1720 ASSIGN(flags);
1721 COPY(pq_u);
1722
1723 ASSIGN(qid);
1724 break;
1725 }
1726 default:
1727 panic("%s: unhandled struct pfioc_altq version", __func__);
1728 break;
1729 }
1730
1731 #undef ASSIGN
1732 #undef COPY
1733 #undef SATU16
1734 #undef SATU32
1735
1736 return (0);
1737 }
1738
1739 /*
1740 * Handle import to struct pf_kaltq of struct pf_altq from user binaries
1741 * that may be using any version of it.
1742 */
1743 static int
pf_import_kaltq(struct pfioc_altq_v1 * pa,struct pf_altq * q,size_t ioc_size)1744 pf_import_kaltq(struct pfioc_altq_v1 *pa, struct pf_altq *q, size_t ioc_size)
1745 {
1746 u_int32_t version;
1747
1748 if (ioc_size == sizeof(struct pfioc_altq_v0))
1749 version = 0;
1750 else
1751 version = pa->version;
1752
1753 if (version > PFIOC_ALTQ_VERSION)
1754 return (EINVAL);
1755
1756 #define ASSIGN(x) q->x = imported_q->x
1757 #define COPY(x) \
1758 bcopy(&imported_q->x, &q->x, min(sizeof(imported_q->x), sizeof(q->x)))
1759
1760 switch (version) {
1761 case 0: {
1762 struct pf_altq_v0 *imported_q =
1763 &((struct pfioc_altq_v0 *)pa)->altq;
1764
1765 COPY(ifname);
1766
1767 ASSIGN(scheduler);
1768 ASSIGN(tbrsize); /* 16-bit -> 32-bit */
1769 ASSIGN(ifbandwidth); /* 32-bit -> 64-bit */
1770
1771 COPY(qname);
1772 COPY(parent);
1773 ASSIGN(parent_qid);
1774 ASSIGN(bandwidth); /* 32-bit -> 64-bit */
1775 ASSIGN(priority);
1776 ASSIGN(local_flags);
1777
1778 ASSIGN(qlimit);
1779 ASSIGN(flags);
1780
1781 if (imported_q->scheduler == ALTQT_HFSC) {
1782 #define ASSIGN_OPT(x) q->pq_u.hfsc_opts.x = imported_q->pq_u.hfsc_opts.x
1783
1784 /*
1785 * The m1 and m2 parameters are being copied from
1786 * 32-bit to 64-bit.
1787 */
1788 ASSIGN_OPT(rtsc_m1);
1789 ASSIGN_OPT(rtsc_d);
1790 ASSIGN_OPT(rtsc_m2);
1791
1792 ASSIGN_OPT(lssc_m1);
1793 ASSIGN_OPT(lssc_d);
1794 ASSIGN_OPT(lssc_m2);
1795
1796 ASSIGN_OPT(ulsc_m1);
1797 ASSIGN_OPT(ulsc_d);
1798 ASSIGN_OPT(ulsc_m2);
1799
1800 ASSIGN_OPT(flags);
1801
1802 #undef ASSIGN_OPT
1803 } else
1804 COPY(pq_u);
1805
1806 ASSIGN(qid);
1807 break;
1808 }
1809 case 1: {
1810 struct pf_altq_v1 *imported_q =
1811 &((struct pfioc_altq_v1 *)pa)->altq;
1812
1813 COPY(ifname);
1814
1815 ASSIGN(scheduler);
1816 ASSIGN(tbrsize);
1817 ASSIGN(ifbandwidth);
1818
1819 COPY(qname);
1820 COPY(parent);
1821 ASSIGN(parent_qid);
1822 ASSIGN(bandwidth);
1823 ASSIGN(priority);
1824 ASSIGN(local_flags);
1825
1826 ASSIGN(qlimit);
1827 ASSIGN(flags);
1828 COPY(pq_u);
1829
1830 ASSIGN(qid);
1831 break;
1832 }
1833 default:
1834 panic("%s: unhandled struct pfioc_altq version", __func__);
1835 break;
1836 }
1837
1838 #undef ASSIGN
1839 #undef COPY
1840
1841 return (0);
1842 }
1843
1844 static struct pf_altq *
pf_altq_get_nth_active(u_int32_t n)1845 pf_altq_get_nth_active(u_int32_t n)
1846 {
1847 struct pf_altq *altq;
1848 u_int32_t nr;
1849
1850 nr = 0;
1851 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
1852 if (nr == n)
1853 return (altq);
1854 nr++;
1855 }
1856
1857 TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
1858 if (nr == n)
1859 return (altq);
1860 nr++;
1861 }
1862
1863 return (NULL);
1864 }
1865 #endif /* ALTQ */
1866
1867 struct pf_krule *
pf_krule_alloc(void)1868 pf_krule_alloc(void)
1869 {
1870 struct pf_krule *rule;
1871
1872 rule = malloc(sizeof(struct pf_krule), M_PFRULE, M_WAITOK | M_ZERO);
1873 mtx_init(&rule->nat.mtx, "pf_krule_nat_pool", NULL, MTX_DEF);
1874 mtx_init(&rule->rdr.mtx, "pf_krule_rdr_pool", NULL, MTX_DEF);
1875 mtx_init(&rule->route.mtx, "pf_krule_route_pool", NULL, MTX_DEF);
1876 rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
1877 M_WAITOK | M_ZERO);
1878 return (rule);
1879 }
1880
1881 void
pf_krule_free(struct pf_krule * rule)1882 pf_krule_free(struct pf_krule *rule)
1883 {
1884 #ifdef PF_WANT_32_TO_64_COUNTER
1885 bool wowned;
1886 #endif
1887
1888 if (rule == NULL)
1889 return;
1890
1891 #ifdef PF_WANT_32_TO_64_COUNTER
1892 if (rule->allrulelinked) {
1893 wowned = PF_RULES_WOWNED();
1894 if (!wowned)
1895 PF_RULES_WLOCK();
1896 LIST_REMOVE(rule, allrulelist);
1897 V_pf_allrulecount--;
1898 if (!wowned)
1899 PF_RULES_WUNLOCK();
1900 }
1901 #endif
1902
1903 pf_counter_u64_deinit(&rule->evaluations);
1904 for (int i = 0; i < 2; i++) {
1905 pf_counter_u64_deinit(&rule->packets[i]);
1906 pf_counter_u64_deinit(&rule->bytes[i]);
1907 }
1908 counter_u64_free(rule->states_cur);
1909 counter_u64_free(rule->states_tot);
1910 for (pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; sn_type++)
1911 counter_u64_free(rule->src_nodes[sn_type]);
1912 uma_zfree_pcpu(pf_timestamp_pcpu_zone, rule->timestamp);
1913
1914 mtx_destroy(&rule->nat.mtx);
1915 mtx_destroy(&rule->rdr.mtx);
1916 mtx_destroy(&rule->route.mtx);
1917 free(rule, M_PFRULE);
1918 }
1919
1920 void
pf_krule_clear_counters(struct pf_krule * rule)1921 pf_krule_clear_counters(struct pf_krule *rule)
1922 {
1923 pf_counter_u64_zero(&rule->evaluations);
1924 for (int i = 0; i < 2; i++) {
1925 pf_counter_u64_zero(&rule->packets[i]);
1926 pf_counter_u64_zero(&rule->bytes[i]);
1927 }
1928 counter_u64_zero(rule->states_tot);
1929 }
1930
1931 static void
pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr * kpool,struct pf_pooladdr * pool)1932 pf_kpooladdr_to_pooladdr(const struct pf_kpooladdr *kpool,
1933 struct pf_pooladdr *pool)
1934 {
1935
1936 bzero(pool, sizeof(*pool));
1937 bcopy(&kpool->addr, &pool->addr, sizeof(pool->addr));
1938 strlcpy(pool->ifname, kpool->ifname, sizeof(pool->ifname));
1939 }
1940
1941 static int
pf_pooladdr_to_kpooladdr(const struct pf_pooladdr * pool,struct pf_kpooladdr * kpool)1942 pf_pooladdr_to_kpooladdr(const struct pf_pooladdr *pool,
1943 struct pf_kpooladdr *kpool)
1944 {
1945 int ret;
1946
1947 bzero(kpool, sizeof(*kpool));
1948 bcopy(&pool->addr, &kpool->addr, sizeof(kpool->addr));
1949 ret = pf_user_strcpy(kpool->ifname, pool->ifname,
1950 sizeof(kpool->ifname));
1951 return (ret);
1952 }
1953
1954 static void
pf_pool_to_kpool(const struct pf_pool * pool,struct pf_kpool * kpool)1955 pf_pool_to_kpool(const struct pf_pool *pool, struct pf_kpool *kpool)
1956 {
1957 _Static_assert(sizeof(pool->key) == sizeof(kpool->key), "");
1958 _Static_assert(sizeof(pool->counter) == sizeof(kpool->counter), "");
1959
1960 bcopy(&pool->key, &kpool->key, sizeof(kpool->key));
1961 bcopy(&pool->counter, &kpool->counter, sizeof(kpool->counter));
1962
1963 kpool->tblidx = pool->tblidx;
1964 kpool->proxy_port[0] = pool->proxy_port[0];
1965 kpool->proxy_port[1] = pool->proxy_port[1];
1966 kpool->opts = pool->opts;
1967 }
1968
1969 static int
pf_rule_to_krule(const struct pf_rule * rule,struct pf_krule * krule)1970 pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule)
1971 {
1972 int ret;
1973
1974 #ifndef INET
1975 if (rule->af == AF_INET) {
1976 return (EAFNOSUPPORT);
1977 }
1978 #endif /* INET */
1979 #ifndef INET6
1980 if (rule->af == AF_INET6) {
1981 return (EAFNOSUPPORT);
1982 }
1983 #endif /* INET6 */
1984
1985 ret = pf_check_rule_addr(&rule->src);
1986 if (ret != 0)
1987 return (ret);
1988 ret = pf_check_rule_addr(&rule->dst);
1989 if (ret != 0)
1990 return (ret);
1991
1992 bcopy(&rule->src, &krule->src, sizeof(rule->src));
1993 bcopy(&rule->dst, &krule->dst, sizeof(rule->dst));
1994
1995 ret = pf_user_strcpy(krule->label[0], rule->label, sizeof(rule->label));
1996 if (ret != 0)
1997 return (ret);
1998 ret = pf_user_strcpy(krule->ifname, rule->ifname, sizeof(rule->ifname));
1999 if (ret != 0)
2000 return (ret);
2001 ret = pf_user_strcpy(krule->qname, rule->qname, sizeof(rule->qname));
2002 if (ret != 0)
2003 return (ret);
2004 ret = pf_user_strcpy(krule->pqname, rule->pqname, sizeof(rule->pqname));
2005 if (ret != 0)
2006 return (ret);
2007 ret = pf_user_strcpy(krule->tagname, rule->tagname,
2008 sizeof(rule->tagname));
2009 if (ret != 0)
2010 return (ret);
2011 ret = pf_user_strcpy(krule->match_tagname, rule->match_tagname,
2012 sizeof(rule->match_tagname));
2013 if (ret != 0)
2014 return (ret);
2015 ret = pf_user_strcpy(krule->overload_tblname, rule->overload_tblname,
2016 sizeof(rule->overload_tblname));
2017 if (ret != 0)
2018 return (ret);
2019
2020 pf_pool_to_kpool(&rule->rpool, &krule->rdr);
2021
2022 /* Don't allow userspace to set evaluations, packets or bytes. */
2023 /* kif, anchor, overload_tbl are not copied over. */
2024
2025 krule->os_fingerprint = rule->os_fingerprint;
2026
2027 krule->rtableid = rule->rtableid;
2028 /* pf_rule->timeout is smaller than pf_krule->timeout */
2029 bcopy(rule->timeout, krule->timeout, sizeof(rule->timeout));
2030 krule->max_states = rule->max_states;
2031 krule->max_src_nodes = rule->max_src_nodes;
2032 krule->max_src_states = rule->max_src_states;
2033 krule->max_src_conn = rule->max_src_conn;
2034 krule->max_src_conn_rate.limit = rule->max_src_conn_rate.limit;
2035 krule->max_src_conn_rate.seconds = rule->max_src_conn_rate.seconds;
2036 krule->qid = rule->qid;
2037 krule->pqid = rule->pqid;
2038 krule->nr = rule->nr;
2039 krule->prob = rule->prob;
2040 krule->cuid = rule->cuid;
2041 krule->cpid = rule->cpid;
2042
2043 krule->return_icmp = rule->return_icmp;
2044 krule->return_icmp6 = rule->return_icmp6;
2045 krule->max_mss = rule->max_mss;
2046 krule->tag = rule->tag;
2047 krule->match_tag = rule->match_tag;
2048 krule->scrub_flags = rule->scrub_flags;
2049
2050 bcopy(&rule->uid, &krule->uid, sizeof(krule->uid));
2051 bcopy(&rule->gid, &krule->gid, sizeof(krule->gid));
2052
2053 krule->rule_flag = rule->rule_flag;
2054 krule->action = rule->action;
2055 krule->direction = rule->direction;
2056 krule->log = rule->log;
2057 krule->logif = rule->logif;
2058 krule->quick = rule->quick;
2059 krule->ifnot = rule->ifnot;
2060 krule->match_tag_not = rule->match_tag_not;
2061 krule->natpass = rule->natpass;
2062
2063 krule->keep_state = rule->keep_state;
2064 krule->af = rule->af;
2065 krule->proto = rule->proto;
2066 krule->type = rule->type;
2067 krule->code = rule->code;
2068 krule->flags = rule->flags;
2069 krule->flagset = rule->flagset;
2070 krule->min_ttl = rule->min_ttl;
2071 krule->allow_opts = rule->allow_opts;
2072 krule->rt = rule->rt;
2073 krule->return_ttl = rule->return_ttl;
2074 krule->tos = rule->tos;
2075 krule->set_tos = rule->set_tos;
2076
2077 krule->flush = rule->flush;
2078 krule->prio = rule->prio;
2079 krule->set_prio[0] = rule->set_prio[0];
2080 krule->set_prio[1] = rule->set_prio[1];
2081
2082 bcopy(&rule->divert, &krule->divert, sizeof(krule->divert));
2083
2084 return (0);
2085 }
2086
2087 int
pf_ioctl_getrules(struct pfioc_rule * pr)2088 pf_ioctl_getrules(struct pfioc_rule *pr)
2089 {
2090 struct pf_kruleset *ruleset;
2091 struct pf_krule *tail;
2092 int rs_num;
2093
2094 PF_RULES_WLOCK();
2095 ruleset = pf_find_kruleset(pr->anchor);
2096 if (ruleset == NULL) {
2097 PF_RULES_WUNLOCK();
2098 return (EINVAL);
2099 }
2100 rs_num = pf_get_ruleset_number(pr->rule.action);
2101 if (rs_num >= PF_RULESET_MAX) {
2102 PF_RULES_WUNLOCK();
2103 return (EINVAL);
2104 }
2105 tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
2106 pf_krulequeue);
2107 if (tail)
2108 pr->nr = tail->nr + 1;
2109 else
2110 pr->nr = 0;
2111 pr->ticket = ruleset->rules[rs_num].active.ticket;
2112 PF_RULES_WUNLOCK();
2113
2114 return (0);
2115 }
2116
2117 static int
pf_rule_checkaf(struct pf_krule * r)2118 pf_rule_checkaf(struct pf_krule *r)
2119 {
2120 switch (r->af) {
2121 case 0:
2122 if (r->rule_flag & PFRULE_AFTO)
2123 return (EPFNOSUPPORT);
2124 break;
2125 case AF_INET:
2126 if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET6)
2127 return (EPFNOSUPPORT);
2128 break;
2129 #ifdef INET6
2130 case AF_INET6:
2131 if ((r->rule_flag & PFRULE_AFTO) && r->naf != AF_INET)
2132 return (EPFNOSUPPORT);
2133 break;
2134 #endif /* INET6 */
2135 default:
2136 return (EPFNOSUPPORT);
2137 }
2138
2139 if ((r->rule_flag & PFRULE_AFTO) == 0 && r->naf != 0)
2140 return (EPFNOSUPPORT);
2141
2142 return (0);
2143 }
2144
2145 static int
pf_validate_range(uint8_t op,uint16_t port[2])2146 pf_validate_range(uint8_t op, uint16_t port[2])
2147 {
2148 uint16_t a = ntohs(port[0]);
2149 uint16_t b = ntohs(port[1]);
2150
2151 if ((op == PF_OP_RRG && a > b) || /* 34:12, i.e. none */
2152 (op == PF_OP_IRG && a >= b) || /* 34><12, i.e. none */
2153 (op == PF_OP_XRG && a > b)) /* 34<>22, i.e. all */
2154 return 1;
2155 return 0;
2156 }
2157
2158 int
pf_ioctl_addrule(struct pf_krule * rule,uint32_t ticket,uint32_t pool_ticket,const char * anchor,const char * anchor_call,uid_t uid,pid_t pid)2159 pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
2160 uint32_t pool_ticket, const char *anchor, const char *anchor_call,
2161 uid_t uid, pid_t pid)
2162 {
2163 struct pf_kruleset *ruleset;
2164 struct pf_krule *tail;
2165 struct pf_kpooladdr *pa;
2166 struct pfi_kkif *kif = NULL, *rcv_kif = NULL;
2167 int rs_num;
2168 int error = 0;
2169
2170 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
2171 #define ERROUT_UNLOCKED(x) ERROUT_FUNCTION(errout_unlocked, x)
2172
2173 if ((rule->return_icmp >> 8) > ICMP_MAXTYPE)
2174 ERROUT_UNLOCKED(EINVAL);
2175
2176 if ((error = pf_rule_checkaf(rule)))
2177 ERROUT_UNLOCKED(error);
2178 if (pf_validate_range(rule->src.port_op, rule->src.port))
2179 ERROUT_UNLOCKED(EINVAL);
2180 if (pf_validate_range(rule->dst.port_op, rule->dst.port))
2181 ERROUT_UNLOCKED(EINVAL);
2182
2183 if (rule->ifname[0])
2184 kif = pf_kkif_create(M_WAITOK);
2185 if (rule->rcv_ifname[0])
2186 rcv_kif = pf_kkif_create(M_WAITOK);
2187 pf_counter_u64_init(&rule->evaluations, M_WAITOK);
2188 for (int i = 0; i < 2; i++) {
2189 pf_counter_u64_init(&rule->packets[i], M_WAITOK);
2190 pf_counter_u64_init(&rule->bytes[i], M_WAITOK);
2191 }
2192 rule->states_cur = counter_u64_alloc(M_WAITOK);
2193 rule->states_tot = counter_u64_alloc(M_WAITOK);
2194 for (pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; sn_type++)
2195 rule->src_nodes[sn_type] = counter_u64_alloc(M_WAITOK);
2196 rule->cuid = uid;
2197 rule->cpid = pid;
2198 TAILQ_INIT(&rule->rdr.list);
2199 TAILQ_INIT(&rule->nat.list);
2200 TAILQ_INIT(&rule->route.list);
2201
2202 PF_CONFIG_LOCK();
2203 PF_RULES_WLOCK();
2204 #ifdef PF_WANT_32_TO_64_COUNTER
2205 LIST_INSERT_HEAD(&V_pf_allrulelist, rule, allrulelist);
2206 MPASS(!rule->allrulelinked);
2207 rule->allrulelinked = true;
2208 V_pf_allrulecount++;
2209 #endif
2210 ruleset = pf_find_kruleset(anchor);
2211 if (ruleset == NULL)
2212 ERROUT(EINVAL);
2213 rs_num = pf_get_ruleset_number(rule->action);
2214 if (rs_num >= PF_RULESET_MAX)
2215 ERROUT(EINVAL);
2216 if (ticket != ruleset->rules[rs_num].inactive.ticket) {
2217 DPFPRINTF(PF_DEBUG_MISC,
2218 "ticket: %d != [%d]%d", ticket, rs_num,
2219 ruleset->rules[rs_num].inactive.ticket);
2220 ERROUT(EBUSY);
2221 }
2222 if (pool_ticket != V_ticket_pabuf) {
2223 DPFPRINTF(PF_DEBUG_MISC,
2224 "pool_ticket: %d != %d", pool_ticket,
2225 V_ticket_pabuf);
2226 ERROUT(EBUSY);
2227 }
2228 /*
2229 * XXXMJG hack: there is no mechanism to ensure they started the
2230 * transaction. Ticket checked above may happen to match by accident,
2231 * even if nobody called DIOCXBEGIN, let alone this process.
2232 * Partially work around it by checking if the RB tree got allocated,
2233 * see pf_begin_rules.
2234 */
2235 if (ruleset->rules[rs_num].inactive.tree == NULL) {
2236 ERROUT(EINVAL);
2237 }
2238
2239 tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
2240 pf_krulequeue);
2241 if (tail)
2242 rule->nr = tail->nr + 1;
2243 else
2244 rule->nr = 0;
2245 if (rule->ifname[0]) {
2246 rule->kif = pfi_kkif_attach(kif, rule->ifname);
2247 kif = NULL;
2248 pfi_kkif_ref(rule->kif);
2249 } else
2250 rule->kif = NULL;
2251
2252 if (rule->rcv_ifname[0]) {
2253 rule->rcv_kif = pfi_kkif_attach(rcv_kif, rule->rcv_ifname);
2254 rcv_kif = NULL;
2255 pfi_kkif_ref(rule->rcv_kif);
2256 } else
2257 rule->rcv_kif = NULL;
2258
2259 if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
2260 ERROUT(EBUSY);
2261 #ifdef ALTQ
2262 /* set queue IDs */
2263 if (rule->qname[0] != 0) {
2264 if ((rule->qid = pf_qname2qid(rule->qname, true)) == 0)
2265 ERROUT(EBUSY);
2266 else if (rule->pqname[0] != 0) {
2267 if ((rule->pqid =
2268 pf_qname2qid(rule->pqname, true)) == 0)
2269 ERROUT(EBUSY);
2270 } else
2271 rule->pqid = rule->qid;
2272 }
2273 #endif
2274 if (rule->tagname[0])
2275 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
2276 ERROUT(EBUSY);
2277 if (rule->match_tagname[0])
2278 if ((rule->match_tag =
2279 pf_tagname2tag(rule->match_tagname)) == 0)
2280 ERROUT(EBUSY);
2281 if (rule->rt && !rule->direction)
2282 ERROUT(EINVAL);
2283 if (!rule->log)
2284 rule->logif = 0;
2285 if (! pf_init_threshold(&rule->pktrate, rule->pktrate.limit,
2286 rule->pktrate.seconds))
2287 ERROUT(ENOMEM);
2288 if (pf_addr_setup(ruleset, &rule->src.addr, rule->af))
2289 ERROUT(ENOMEM);
2290 if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
2291 ERROUT(ENOMEM);
2292 if (pf_kanchor_setup(rule, ruleset, anchor_call))
2293 ERROUT(EINVAL);
2294 if (rule->scrub_flags & PFSTATE_SETPRIO &&
2295 (rule->set_prio[0] > PF_PRIO_MAX ||
2296 rule->set_prio[1] > PF_PRIO_MAX))
2297 ERROUT(EINVAL);
2298 for (int i = 0; i < 3; i++) {
2299 TAILQ_FOREACH(pa, &V_pf_pabuf[i], entries)
2300 if (pa->addr.type == PF_ADDR_TABLE) {
2301 pa->addr.p.tbl = pfr_attach_table(ruleset,
2302 pa->addr.v.tblname);
2303 if (pa->addr.p.tbl == NULL)
2304 ERROUT(ENOMEM);
2305 }
2306 }
2307
2308 rule->overload_tbl = NULL;
2309 if (rule->overload_tblname[0]) {
2310 if ((rule->overload_tbl = pfr_attach_table(ruleset,
2311 rule->overload_tblname)) == NULL)
2312 ERROUT(EINVAL);
2313 else
2314 rule->overload_tbl->pfrkt_flags |=
2315 PFR_TFLAG_ACTIVE;
2316 }
2317
2318 pf_mv_kpool(&V_pf_pabuf[0], &rule->nat.list);
2319
2320 /*
2321 * Old version of pfctl provide route redirection pools in single
2322 * common redirection pool rdr. New versions use rdr only for
2323 * rdr-to rules.
2324 */
2325 if (rule->rt > PF_NOPFROUTE && TAILQ_EMPTY(&V_pf_pabuf[2])) {
2326 pf_mv_kpool(&V_pf_pabuf[1], &rule->route.list);
2327 } else {
2328 pf_mv_kpool(&V_pf_pabuf[1], &rule->rdr.list);
2329 pf_mv_kpool(&V_pf_pabuf[2], &rule->route.list);
2330 }
2331
2332 if (((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
2333 (rule->action == PF_BINAT)) && rule->anchor == NULL &&
2334 TAILQ_FIRST(&rule->rdr.list) == NULL) {
2335 ERROUT(EINVAL);
2336 }
2337
2338 if (rule->rt > PF_NOPFROUTE && (TAILQ_FIRST(&rule->route.list) == NULL)) {
2339 ERROUT(EINVAL);
2340 }
2341
2342 if (rule->action == PF_PASS && (rule->rdr.opts & PF_POOL_STICKYADDR ||
2343 rule->nat.opts & PF_POOL_STICKYADDR) && !rule->keep_state) {
2344 ERROUT(EINVAL);
2345 }
2346
2347 MPASS(error == 0);
2348
2349 rule->nat.cur = TAILQ_FIRST(&rule->nat.list);
2350 rule->rdr.cur = TAILQ_FIRST(&rule->rdr.list);
2351 rule->route.cur = TAILQ_FIRST(&rule->route.list);
2352 rule->route.ipv6_nexthop_af = AF_INET6;
2353 TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
2354 rule, entries);
2355 ruleset->rules[rs_num].inactive.rcount++;
2356
2357 PF_RULES_WUNLOCK();
2358 pf_hash_rule(rule);
2359 if (RB_INSERT(pf_krule_global, ruleset->rules[rs_num].inactive.tree, rule) != NULL) {
2360 PF_RULES_WLOCK();
2361 TAILQ_REMOVE(ruleset->rules[rs_num].inactive.ptr, rule, entries);
2362 ruleset->rules[rs_num].inactive.rcount--;
2363 pf_free_rule(rule);
2364 rule = NULL;
2365 ERROUT(EEXIST);
2366 }
2367 PF_CONFIG_UNLOCK();
2368
2369 return (0);
2370
2371 #undef ERROUT
2372 #undef ERROUT_UNLOCKED
2373 errout:
2374 PF_RULES_WUNLOCK();
2375 PF_CONFIG_UNLOCK();
2376 errout_unlocked:
2377 pf_kkif_free(rcv_kif);
2378 pf_kkif_free(kif);
2379 pf_krule_free(rule);
2380 return (error);
2381 }
2382
2383 static bool
pf_label_match(const struct pf_krule * rule,const char * label)2384 pf_label_match(const struct pf_krule *rule, const char *label)
2385 {
2386 int i = 0;
2387
2388 while (*rule->label[i]) {
2389 if (strcmp(rule->label[i], label) == 0)
2390 return (true);
2391 i++;
2392 }
2393
2394 return (false);
2395 }
2396
2397 static unsigned int
pf_kill_matching_state(struct pf_state_key_cmp * key,int dir)2398 pf_kill_matching_state(struct pf_state_key_cmp *key, int dir)
2399 {
2400 struct pf_kstate *s;
2401 int more = 0;
2402
2403 s = pf_find_state_all(key, dir, &more);
2404 if (s == NULL)
2405 return (0);
2406
2407 if (more) {
2408 PF_STATE_UNLOCK(s);
2409 return (0);
2410 }
2411
2412 pf_remove_state(s);
2413 return (1);
2414 }
2415
2416 static int
pf_killstates_row(struct pf_kstate_kill * psk,struct pf_idhash * ih)2417 pf_killstates_row(struct pf_kstate_kill *psk, struct pf_idhash *ih)
2418 {
2419 struct pf_kstate *s;
2420 struct pf_state_key *sk;
2421 struct pf_addr *srcaddr, *dstaddr;
2422 struct pf_state_key_cmp match_key;
2423 int idx, killed = 0;
2424 unsigned int dir;
2425 u_int16_t srcport, dstport;
2426 struct pfi_kkif *kif;
2427
2428 relock_DIOCKILLSTATES:
2429 PF_HASHROW_LOCK(ih);
2430 LIST_FOREACH(s, &ih->states, entry) {
2431 /* For floating states look at the original kif. */
2432 kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
2433
2434 sk = s->key[psk->psk_nat ? PF_SK_STACK : PF_SK_WIRE];
2435 if (s->direction == PF_OUT) {
2436 srcaddr = &sk->addr[1];
2437 dstaddr = &sk->addr[0];
2438 srcport = sk->port[1];
2439 dstport = sk->port[0];
2440 } else {
2441 srcaddr = &sk->addr[0];
2442 dstaddr = &sk->addr[1];
2443 srcport = sk->port[0];
2444 dstport = sk->port[1];
2445 }
2446
2447 if (psk->psk_af && sk->af != psk->psk_af)
2448 continue;
2449
2450 if (psk->psk_proto && psk->psk_proto != sk->proto)
2451 continue;
2452
2453 if (! pf_match_addr(psk->psk_src.neg,
2454 &psk->psk_src.addr.v.a.addr,
2455 &psk->psk_src.addr.v.a.mask, srcaddr, sk->af))
2456 continue;
2457
2458 if (! pf_match_addr(psk->psk_dst.neg,
2459 &psk->psk_dst.addr.v.a.addr,
2460 &psk->psk_dst.addr.v.a.mask, dstaddr, sk->af))
2461 continue;
2462
2463 if (! pf_match_addr(psk->psk_rt_addr.neg,
2464 &psk->psk_rt_addr.addr.v.a.addr,
2465 &psk->psk_rt_addr.addr.v.a.mask,
2466 &s->act.rt_addr, sk->af))
2467 continue;
2468
2469 if (psk->psk_src.port_op != 0 &&
2470 ! pf_match_port(psk->psk_src.port_op,
2471 psk->psk_src.port[0], psk->psk_src.port[1], srcport))
2472 continue;
2473
2474 if (psk->psk_dst.port_op != 0 &&
2475 ! pf_match_port(psk->psk_dst.port_op,
2476 psk->psk_dst.port[0], psk->psk_dst.port[1], dstport))
2477 continue;
2478
2479 if (psk->psk_label[0] &&
2480 ! pf_label_match(s->rule, psk->psk_label))
2481 continue;
2482
2483 if (psk->psk_ifname[0] && strcmp(psk->psk_ifname,
2484 kif->pfik_name))
2485 continue;
2486
2487 if (psk->psk_kill_match) {
2488 /* Create the key to find matching states, with lock
2489 * held. */
2490
2491 bzero(&match_key, sizeof(match_key));
2492
2493 if (s->direction == PF_OUT) {
2494 dir = PF_IN;
2495 idx = psk->psk_nat ? PF_SK_WIRE : PF_SK_STACK;
2496 } else {
2497 dir = PF_OUT;
2498 idx = psk->psk_nat ? PF_SK_STACK : PF_SK_WIRE;
2499 }
2500
2501 match_key.af = s->key[idx]->af;
2502 match_key.proto = s->key[idx]->proto;
2503 pf_addrcpy(&match_key.addr[0],
2504 &s->key[idx]->addr[1], match_key.af);
2505 match_key.port[0] = s->key[idx]->port[1];
2506 pf_addrcpy(&match_key.addr[1],
2507 &s->key[idx]->addr[0], match_key.af);
2508 match_key.port[1] = s->key[idx]->port[0];
2509 }
2510
2511 pf_remove_state(s);
2512 killed++;
2513
2514 if (psk->psk_kill_match)
2515 killed += pf_kill_matching_state(&match_key, dir);
2516
2517 goto relock_DIOCKILLSTATES;
2518 }
2519 PF_HASHROW_UNLOCK(ih);
2520
2521 return (killed);
2522 }
2523
2524 void
unhandled_af(int af)2525 unhandled_af(int af)
2526 {
2527 panic("unhandled af %d", af);
2528 }
2529
2530 int
pf_start(void)2531 pf_start(void)
2532 {
2533 int error = 0;
2534
2535 sx_xlock(&V_pf_ioctl_lock);
2536 if (V_pf_status.running)
2537 error = EEXIST;
2538 else {
2539 hook_pf();
2540 if (! TAILQ_EMPTY(V_pf_keth->active.rules))
2541 hook_pf_eth();
2542 V_pf_status.running = 1;
2543 V_pf_status.since = time_uptime;
2544 new_unrhdr64(&V_pf_stateid, time_second);
2545
2546 DPFPRINTF(PF_DEBUG_MISC, "pf: started");
2547 }
2548 sx_xunlock(&V_pf_ioctl_lock);
2549
2550 return (error);
2551 }
2552
2553 int
pf_stop(void)2554 pf_stop(void)
2555 {
2556 int error = 0;
2557
2558 sx_xlock(&V_pf_ioctl_lock);
2559 if (!V_pf_status.running)
2560 error = ENOENT;
2561 else {
2562 V_pf_status.running = 0;
2563 dehook_pf();
2564 dehook_pf_eth();
2565 V_pf_status.since = time_uptime;
2566 DPFPRINTF(PF_DEBUG_MISC, "pf: stopped");
2567 }
2568 sx_xunlock(&V_pf_ioctl_lock);
2569
2570 return (error);
2571 }
2572
2573 void
pf_ioctl_clear_status(void)2574 pf_ioctl_clear_status(void)
2575 {
2576 PF_RULES_WLOCK();
2577 for (int i = 0; i < PFRES_MAX; i++)
2578 counter_u64_zero(V_pf_status.counters[i]);
2579 for (int i = 0; i < FCNT_MAX; i++)
2580 pf_counter_u64_zero(&V_pf_status.fcounters[i]);
2581 for (int i = 0; i < SCNT_MAX; i++)
2582 counter_u64_zero(V_pf_status.scounters[i]);
2583 for (int i = 0; i < NCNT_MAX; i++)
2584 counter_u64_zero(V_pf_status.ncounters[i]);
2585 for (int i = 0; i < KLCNT_MAX; i++)
2586 counter_u64_zero(V_pf_status.lcounters[i]);
2587 V_pf_status.since = time_uptime;
2588 if (*V_pf_status.ifname)
2589 pfi_update_status(V_pf_status.ifname, NULL);
2590 PF_RULES_WUNLOCK();
2591 }
2592
2593 int
pf_ioctl_set_timeout(int timeout,int seconds,int * prev_seconds)2594 pf_ioctl_set_timeout(int timeout, int seconds, int *prev_seconds)
2595 {
2596 uint32_t old;
2597
2598 if (timeout < 0 || timeout >= PFTM_MAX ||
2599 seconds < 0)
2600 return (EINVAL);
2601
2602 PF_RULES_WLOCK();
2603 old = V_pf_default_rule.timeout[timeout];
2604 if (timeout == PFTM_INTERVAL && seconds == 0)
2605 seconds = 1;
2606 V_pf_default_rule.timeout[timeout] = seconds;
2607 if (timeout == PFTM_INTERVAL && seconds < old)
2608 wakeup(pf_purge_thread);
2609
2610 if (prev_seconds != NULL)
2611 *prev_seconds = old;
2612
2613 PF_RULES_WUNLOCK();
2614
2615 return (0);
2616 }
2617
2618 int
pf_ioctl_get_timeout(int timeout,int * seconds)2619 pf_ioctl_get_timeout(int timeout, int *seconds)
2620 {
2621 PF_RULES_RLOCK_TRACKER;
2622
2623 if (timeout < 0 || timeout >= PFTM_MAX)
2624 return (EINVAL);
2625
2626 PF_RULES_RLOCK();
2627 *seconds = V_pf_default_rule.timeout[timeout];
2628 PF_RULES_RUNLOCK();
2629
2630 return (0);
2631 }
2632
2633 int
pf_ioctl_set_limit(int index,unsigned int limit,unsigned int * old_limit)2634 pf_ioctl_set_limit(int index, unsigned int limit, unsigned int *old_limit)
2635 {
2636
2637 PF_RULES_WLOCK();
2638 if (index < 0 || index >= PF_LIMIT_MAX ||
2639 V_pf_limits[index].zone == NULL) {
2640 PF_RULES_WUNLOCK();
2641 return (EINVAL);
2642 }
2643 uma_zone_set_max(V_pf_limits[index].zone,
2644 limit == 0 ? INT_MAX : limit);
2645 if (old_limit != NULL)
2646 *old_limit = V_pf_limits[index].limit;
2647 V_pf_limits[index].limit = limit;
2648 PF_RULES_WUNLOCK();
2649
2650 return (0);
2651 }
2652
2653 int
pf_ioctl_get_limit(int index,unsigned int * limit)2654 pf_ioctl_get_limit(int index, unsigned int *limit)
2655 {
2656 PF_RULES_RLOCK_TRACKER;
2657
2658 if (index < 0 || index >= PF_LIMIT_MAX)
2659 return (EINVAL);
2660
2661 PF_RULES_RLOCK();
2662 *limit = V_pf_limits[index].limit;
2663 PF_RULES_RUNLOCK();
2664
2665 return (0);
2666 }
2667
2668 int
pf_ioctl_begin_addrs(uint32_t * ticket)2669 pf_ioctl_begin_addrs(uint32_t *ticket)
2670 {
2671 PF_RULES_WLOCK();
2672 pf_empty_kpool(&V_pf_pabuf[0]);
2673 pf_empty_kpool(&V_pf_pabuf[1]);
2674 pf_empty_kpool(&V_pf_pabuf[2]);
2675 *ticket = ++V_ticket_pabuf;
2676 PF_RULES_WUNLOCK();
2677
2678 return (0);
2679 }
2680
2681 int
pf_ioctl_add_addr(struct pf_nl_pooladdr * pp)2682 pf_ioctl_add_addr(struct pf_nl_pooladdr *pp)
2683 {
2684 struct pf_kpooladdr *pa = NULL;
2685 struct pfi_kkif *kif = NULL;
2686 int error;
2687
2688 if (pp->which != PF_RDR && pp->which != PF_NAT &&
2689 pp->which != PF_RT)
2690 return (EINVAL);
2691
2692 switch (pp->af) {
2693 #ifdef INET
2694 case AF_INET:
2695 /* FALLTHROUGH */
2696 #endif /* INET */
2697 #ifdef INET6
2698 case AF_INET6:
2699 /* FALLTHROUGH */
2700 #endif /* INET6 */
2701 case AF_UNSPEC:
2702 break;
2703 default:
2704 return (EAFNOSUPPORT);
2705 }
2706
2707 if (pp->addr.addr.type != PF_ADDR_ADDRMASK &&
2708 pp->addr.addr.type != PF_ADDR_DYNIFTL &&
2709 pp->addr.addr.type != PF_ADDR_TABLE)
2710 return (EINVAL);
2711
2712 if (pp->addr.addr.p.dyn != NULL)
2713 return (EINVAL);
2714
2715 pa = malloc(sizeof(*pa), M_PFRULE, M_WAITOK);
2716 error = pf_pooladdr_to_kpooladdr(&pp->addr, pa);
2717 if (error != 0)
2718 goto out;
2719 if (pa->ifname[0])
2720 kif = pf_kkif_create(M_WAITOK);
2721 PF_RULES_WLOCK();
2722 if (pp->ticket != V_ticket_pabuf) {
2723 PF_RULES_WUNLOCK();
2724 if (pa->ifname[0])
2725 pf_kkif_free(kif);
2726 error = EBUSY;
2727 goto out;
2728 }
2729 if (pa->ifname[0]) {
2730 pa->kif = pfi_kkif_attach(kif, pa->ifname);
2731 kif = NULL;
2732 pfi_kkif_ref(pa->kif);
2733 } else
2734 pa->kif = NULL;
2735 if (pa->addr.type == PF_ADDR_DYNIFTL && ((error =
2736 pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) {
2737 if (pa->ifname[0])
2738 pfi_kkif_unref(pa->kif);
2739 PF_RULES_WUNLOCK();
2740 goto out;
2741 }
2742 pa->af = pp->af;
2743 switch (pp->which) {
2744 case PF_NAT:
2745 TAILQ_INSERT_TAIL(&V_pf_pabuf[0], pa, entries);
2746 break;
2747 case PF_RDR:
2748 TAILQ_INSERT_TAIL(&V_pf_pabuf[1], pa, entries);
2749 break;
2750 case PF_RT:
2751 TAILQ_INSERT_TAIL(&V_pf_pabuf[2], pa, entries);
2752 break;
2753 }
2754 PF_RULES_WUNLOCK();
2755
2756 return (0);
2757
2758 out:
2759 free(pa, M_PFRULE);
2760 return (error);
2761 }
2762
2763 int
pf_ioctl_get_addrs(struct pf_nl_pooladdr * pp)2764 pf_ioctl_get_addrs(struct pf_nl_pooladdr *pp)
2765 {
2766 struct pf_kpool *pool;
2767 struct pf_kpooladdr *pa;
2768
2769 PF_RULES_RLOCK_TRACKER;
2770
2771 if (pp->which != PF_RDR && pp->which != PF_NAT &&
2772 pp->which != PF_RT)
2773 return (EINVAL);
2774
2775 pp->anchor[sizeof(pp->anchor) - 1] = 0;
2776 pp->nr = 0;
2777
2778 PF_RULES_RLOCK();
2779 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
2780 pp->r_num, 0, 1, 0, pp->which);
2781 if (pool == NULL) {
2782 PF_RULES_RUNLOCK();
2783 return (EBUSY);
2784 }
2785 TAILQ_FOREACH(pa, &pool->list, entries)
2786 pp->nr++;
2787 PF_RULES_RUNLOCK();
2788
2789 return (0);
2790 }
2791
2792 int
pf_ioctl_get_addr(struct pf_nl_pooladdr * pp)2793 pf_ioctl_get_addr(struct pf_nl_pooladdr *pp)
2794 {
2795 struct pf_kpool *pool;
2796 struct pf_kpooladdr *pa;
2797 u_int32_t nr = 0;
2798
2799 if (pp->which != PF_RDR && pp->which != PF_NAT &&
2800 pp->which != PF_RT)
2801 return (EINVAL);
2802
2803 PF_RULES_RLOCK_TRACKER;
2804
2805 pp->anchor[sizeof(pp->anchor) - 1] = '\0';
2806
2807 PF_RULES_RLOCK();
2808 pool = pf_get_kpool(pp->anchor, pp->ticket, pp->r_action,
2809 pp->r_num, 0, 1, 1, pp->which);
2810 if (pool == NULL) {
2811 PF_RULES_RUNLOCK();
2812 return (EBUSY);
2813 }
2814 pa = TAILQ_FIRST(&pool->list);
2815 while ((pa != NULL) && (nr < pp->nr)) {
2816 pa = TAILQ_NEXT(pa, entries);
2817 nr++;
2818 }
2819 if (pa == NULL) {
2820 PF_RULES_RUNLOCK();
2821 return (EBUSY);
2822 }
2823 pf_kpooladdr_to_pooladdr(pa, &pp->addr);
2824 pp->af = pa->af;
2825 pf_addr_copyout(&pp->addr.addr);
2826 PF_RULES_RUNLOCK();
2827
2828 return (0);
2829 }
2830
2831 int
pf_ioctl_get_rulesets(struct pfioc_ruleset * pr)2832 pf_ioctl_get_rulesets(struct pfioc_ruleset *pr)
2833 {
2834 struct pf_kruleset *ruleset;
2835 struct pf_kanchor *anchor;
2836
2837 PF_RULES_RLOCK_TRACKER;
2838
2839 pr->path[sizeof(pr->path) - 1] = '\0';
2840
2841 PF_RULES_RLOCK();
2842 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
2843 PF_RULES_RUNLOCK();
2844 return (ENOENT);
2845 }
2846 pr->nr = 0;
2847 if (ruleset == &pf_main_ruleset) {
2848 /* XXX kludge for pf_main_ruleset */
2849 RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
2850 if (anchor->parent == NULL)
2851 pr->nr++;
2852 } else {
2853 RB_FOREACH(anchor, pf_kanchor_node,
2854 &ruleset->anchor->children)
2855 pr->nr++;
2856 }
2857 PF_RULES_RUNLOCK();
2858
2859 return (0);
2860 }
2861
2862 int
pf_ioctl_get_ruleset(struct pfioc_ruleset * pr)2863 pf_ioctl_get_ruleset(struct pfioc_ruleset *pr)
2864 {
2865 struct pf_kruleset *ruleset;
2866 struct pf_kanchor *anchor;
2867 u_int32_t nr = 0;
2868 int error = 0;
2869
2870 PF_RULES_RLOCK_TRACKER;
2871
2872 PF_RULES_RLOCK();
2873 if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
2874 PF_RULES_RUNLOCK();
2875 return (ENOENT);
2876 }
2877
2878 pr->name[0] = '\0';
2879 if (ruleset == &pf_main_ruleset) {
2880 /* XXX kludge for pf_main_ruleset */
2881 RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
2882 if (anchor->parent == NULL && nr++ == pr->nr) {
2883 strlcpy(pr->name, anchor->name,
2884 sizeof(pr->name));
2885 break;
2886 }
2887 } else {
2888 RB_FOREACH(anchor, pf_kanchor_node,
2889 &ruleset->anchor->children)
2890 if (nr++ == pr->nr) {
2891 strlcpy(pr->name, anchor->name,
2892 sizeof(pr->name));
2893 break;
2894 }
2895 }
2896 if (!pr->name[0])
2897 error = EBUSY;
2898 PF_RULES_RUNLOCK();
2899
2900 return (error);
2901 }
2902
2903 int
pf_ioctl_natlook(struct pfioc_natlook * pnl)2904 pf_ioctl_natlook(struct pfioc_natlook *pnl)
2905 {
2906 struct pf_state_key *sk;
2907 struct pf_kstate *state;
2908 struct pf_state_key_cmp key;
2909 int m = 0, direction = pnl->direction;
2910 int sidx, didx;
2911
2912 /* NATLOOK src and dst are reversed, so reverse sidx/didx */
2913 sidx = (direction == PF_IN) ? 1 : 0;
2914 didx = (direction == PF_IN) ? 0 : 1;
2915
2916 if (!pnl->proto ||
2917 PF_AZERO(&pnl->saddr, pnl->af) ||
2918 PF_AZERO(&pnl->daddr, pnl->af) ||
2919 ((pnl->proto == IPPROTO_TCP ||
2920 pnl->proto == IPPROTO_UDP) &&
2921 (!pnl->dport || !pnl->sport)))
2922 return (EINVAL);
2923
2924 switch (pnl->direction) {
2925 case PF_IN:
2926 case PF_OUT:
2927 case PF_INOUT:
2928 break;
2929 default:
2930 return (EINVAL);
2931 }
2932
2933 switch (pnl->af) {
2934 #ifdef INET
2935 case AF_INET:
2936 break;
2937 #endif /* INET */
2938 #ifdef INET6
2939 case AF_INET6:
2940 break;
2941 #endif /* INET6 */
2942 default:
2943 return (EAFNOSUPPORT);
2944 }
2945
2946 bzero(&key, sizeof(key));
2947 key.af = pnl->af;
2948 key.proto = pnl->proto;
2949 pf_addrcpy(&key.addr[sidx], &pnl->saddr, pnl->af);
2950 key.port[sidx] = pnl->sport;
2951 pf_addrcpy(&key.addr[didx], &pnl->daddr, pnl->af);
2952 key.port[didx] = pnl->dport;
2953
2954 state = pf_find_state_all(&key, direction, &m);
2955 if (state == NULL)
2956 return (ENOENT);
2957
2958 if (m > 1) {
2959 PF_STATE_UNLOCK(state);
2960 return (E2BIG); /* more than one state */
2961 }
2962
2963 sk = state->key[sidx];
2964 pf_addrcpy(&pnl->rsaddr,
2965 &sk->addr[sidx], sk->af);
2966 pnl->rsport = sk->port[sidx];
2967 pf_addrcpy(&pnl->rdaddr,
2968 &sk->addr[didx], sk->af);
2969 pnl->rdport = sk->port[didx];
2970 PF_STATE_UNLOCK(state);
2971
2972 return (0);
2973 }
2974
2975 static int
pfioctl(struct cdev * dev,u_long cmd,caddr_t addr,int flags,struct thread * td)2976 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
2977 {
2978 int error = 0;
2979 PF_RULES_RLOCK_TRACKER;
2980
2981 #define ERROUT_IOCTL(target, x) \
2982 do { \
2983 error = (x); \
2984 SDT_PROBE3(pf, ioctl, ioctl, error, cmd, error, __LINE__); \
2985 goto target; \
2986 } while (0)
2987
2988
2989 /* XXX keep in sync with switch() below */
2990 if (securelevel_gt(td->td_ucred, 2))
2991 switch (cmd) {
2992 case DIOCGETRULES:
2993 case DIOCGETRULENV:
2994 case DIOCGETADDRS:
2995 case DIOCGETADDR:
2996 case DIOCGETSTATE:
2997 case DIOCGETSTATENV:
2998 case DIOCSETSTATUSIF:
2999 case DIOCGETSTATUSNV:
3000 case DIOCCLRSTATUS:
3001 case DIOCNATLOOK:
3002 case DIOCSETDEBUG:
3003 #ifdef COMPAT_FREEBSD14
3004 case DIOCGETSTATES:
3005 case DIOCGETSTATESV2:
3006 #endif
3007 case DIOCGETTIMEOUT:
3008 case DIOCCLRRULECTRS:
3009 case DIOCGETLIMIT:
3010 case DIOCGETALTQSV0:
3011 case DIOCGETALTQSV1:
3012 case DIOCGETALTQV0:
3013 case DIOCGETALTQV1:
3014 case DIOCGETQSTATSV0:
3015 case DIOCGETQSTATSV1:
3016 case DIOCGETRULESETS:
3017 case DIOCGETRULESET:
3018 case DIOCRGETTABLES:
3019 case DIOCRGETTSTATS:
3020 case DIOCRCLRTSTATS:
3021 case DIOCRCLRADDRS:
3022 case DIOCRADDADDRS:
3023 case DIOCRDELADDRS:
3024 case DIOCRSETADDRS:
3025 case DIOCRGETADDRS:
3026 case DIOCRGETASTATS:
3027 case DIOCRCLRASTATS:
3028 case DIOCRTSTADDRS:
3029 case DIOCOSFPGET:
3030 case DIOCGETSRCNODES:
3031 case DIOCCLRSRCNODES:
3032 case DIOCGETSYNCOOKIES:
3033 case DIOCIGETIFACES:
3034 case DIOCGIFSPEEDV0:
3035 case DIOCGIFSPEEDV1:
3036 case DIOCSETIFFLAG:
3037 case DIOCCLRIFFLAG:
3038 case DIOCGETETHRULES:
3039 case DIOCGETETHRULE:
3040 case DIOCGETETHRULESETS:
3041 case DIOCGETETHRULESET:
3042 break;
3043 case DIOCRCLRTABLES:
3044 case DIOCRADDTABLES:
3045 case DIOCRDELTABLES:
3046 case DIOCRSETTFLAGS:
3047 if (((struct pfioc_table *)addr)->pfrio_flags &
3048 PFR_FLAG_DUMMY)
3049 break; /* dummy operation ok */
3050 return (EPERM);
3051 default:
3052 return (EPERM);
3053 }
3054
3055 if (!(flags & FWRITE))
3056 switch (cmd) {
3057 case DIOCGETRULES:
3058 case DIOCGETADDRS:
3059 case DIOCGETADDR:
3060 case DIOCGETSTATE:
3061 case DIOCGETSTATENV:
3062 case DIOCGETSTATUSNV:
3063 #ifdef COMPAT_FREEBSD14
3064 case DIOCGETSTATES:
3065 case DIOCGETSTATESV2:
3066 #endif
3067 case DIOCGETTIMEOUT:
3068 case DIOCGETLIMIT:
3069 case DIOCGETALTQSV0:
3070 case DIOCGETALTQSV1:
3071 case DIOCGETALTQV0:
3072 case DIOCGETALTQV1:
3073 case DIOCGETQSTATSV0:
3074 case DIOCGETQSTATSV1:
3075 case DIOCGETRULESETS:
3076 case DIOCGETRULESET:
3077 case DIOCNATLOOK:
3078 case DIOCRGETTABLES:
3079 case DIOCRGETTSTATS:
3080 case DIOCRGETADDRS:
3081 case DIOCRGETASTATS:
3082 case DIOCRTSTADDRS:
3083 case DIOCOSFPGET:
3084 case DIOCGETSRCNODES:
3085 case DIOCGETSYNCOOKIES:
3086 case DIOCIGETIFACES:
3087 case DIOCGIFSPEEDV1:
3088 case DIOCGIFSPEEDV0:
3089 case DIOCGETRULENV:
3090 case DIOCGETETHRULES:
3091 case DIOCGETETHRULE:
3092 case DIOCGETETHRULESETS:
3093 case DIOCGETETHRULESET:
3094 break;
3095 case DIOCRCLRTABLES:
3096 case DIOCRADDTABLES:
3097 case DIOCRDELTABLES:
3098 case DIOCRCLRTSTATS:
3099 case DIOCRCLRADDRS:
3100 case DIOCRADDADDRS:
3101 case DIOCRDELADDRS:
3102 case DIOCRSETADDRS:
3103 case DIOCRSETTFLAGS:
3104 if (((struct pfioc_table *)addr)->pfrio_flags &
3105 PFR_FLAG_DUMMY) {
3106 flags |= FWRITE; /* need write lock for dummy */
3107 break; /* dummy operation ok */
3108 }
3109 return (EACCES);
3110 default:
3111 return (EACCES);
3112 }
3113
3114 CURVNET_SET(TD_TO_VNET(td));
3115
3116 switch (cmd) {
3117 #ifdef COMPAT_FREEBSD14
3118 case DIOCSTART:
3119 error = pf_start();
3120 break;
3121
3122 case DIOCSTOP:
3123 error = pf_stop();
3124 break;
3125 #endif
3126
3127 case DIOCGETETHRULES: {
3128 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
3129 nvlist_t *nvl;
3130 void *packed;
3131 struct pf_keth_rule *tail;
3132 struct pf_keth_ruleset *rs;
3133 u_int32_t ticket, nr;
3134 const char *anchor = "";
3135
3136 nvl = NULL;
3137 packed = NULL;
3138
3139 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULES_error, x)
3140
3141 if (nv->len > pf_ioctl_maxcount)
3142 ERROUT(ENOMEM);
3143
3144 /* Copy the request in */
3145 packed = malloc(nv->len, M_NVLIST, M_WAITOK);
3146 error = copyin(nv->data, packed, nv->len);
3147 if (error)
3148 ERROUT(error);
3149
3150 nvl = nvlist_unpack(packed, nv->len, 0);
3151 if (nvl == NULL)
3152 ERROUT(EBADMSG);
3153
3154 if (! nvlist_exists_string(nvl, "anchor"))
3155 ERROUT(EBADMSG);
3156
3157 anchor = nvlist_get_string(nvl, "anchor");
3158
3159 rs = pf_find_keth_ruleset(anchor);
3160
3161 nvlist_destroy(nvl);
3162 nvl = NULL;
3163 free(packed, M_NVLIST);
3164 packed = NULL;
3165
3166 if (rs == NULL)
3167 ERROUT(ENOENT);
3168
3169 /* Reply */
3170 nvl = nvlist_create(0);
3171 if (nvl == NULL)
3172 ERROUT(ENOMEM);
3173
3174 PF_RULES_RLOCK();
3175
3176 ticket = rs->active.ticket;
3177 tail = TAILQ_LAST(rs->active.rules, pf_keth_ruleq);
3178 if (tail)
3179 nr = tail->nr + 1;
3180 else
3181 nr = 0;
3182
3183 PF_RULES_RUNLOCK();
3184
3185 nvlist_add_number(nvl, "ticket", ticket);
3186 nvlist_add_number(nvl, "nr", nr);
3187
3188 packed = nvlist_pack(nvl, &nv->len);
3189 if (packed == NULL)
3190 ERROUT(ENOMEM);
3191
3192 if (nv->size == 0)
3193 ERROUT(0);
3194 else if (nv->size < nv->len)
3195 ERROUT(ENOSPC);
3196
3197 error = copyout(packed, nv->data, nv->len);
3198
3199 #undef ERROUT
3200 DIOCGETETHRULES_error:
3201 free(packed, M_NVLIST);
3202 nvlist_destroy(nvl);
3203 break;
3204 }
3205
3206 case DIOCGETETHRULE: {
3207 struct epoch_tracker et;
3208 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
3209 nvlist_t *nvl = NULL;
3210 void *nvlpacked = NULL;
3211 struct pf_keth_rule *rule = NULL;
3212 struct pf_keth_ruleset *rs;
3213 u_int32_t ticket, nr;
3214 bool clear = false;
3215 const char *anchor;
3216
3217 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULE_error, x)
3218
3219 if (nv->len > pf_ioctl_maxcount)
3220 ERROUT(ENOMEM);
3221
3222 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3223 error = copyin(nv->data, nvlpacked, nv->len);
3224 if (error)
3225 ERROUT(error);
3226
3227 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3228 if (nvl == NULL)
3229 ERROUT(EBADMSG);
3230 if (! nvlist_exists_number(nvl, "ticket"))
3231 ERROUT(EBADMSG);
3232 ticket = nvlist_get_number(nvl, "ticket");
3233 if (! nvlist_exists_string(nvl, "anchor"))
3234 ERROUT(EBADMSG);
3235 anchor = nvlist_get_string(nvl, "anchor");
3236
3237 if (nvlist_exists_bool(nvl, "clear"))
3238 clear = nvlist_get_bool(nvl, "clear");
3239
3240 if (clear && !(flags & FWRITE))
3241 ERROUT(EACCES);
3242
3243 if (! nvlist_exists_number(nvl, "nr"))
3244 ERROUT(EBADMSG);
3245 nr = nvlist_get_number(nvl, "nr");
3246
3247 PF_RULES_RLOCK();
3248 rs = pf_find_keth_ruleset(anchor);
3249 if (rs == NULL) {
3250 PF_RULES_RUNLOCK();
3251 ERROUT(ENOENT);
3252 }
3253 if (ticket != rs->active.ticket) {
3254 PF_RULES_RUNLOCK();
3255 ERROUT(EBUSY);
3256 }
3257
3258 nvlist_destroy(nvl);
3259 nvl = NULL;
3260 free(nvlpacked, M_NVLIST);
3261 nvlpacked = NULL;
3262
3263 rule = TAILQ_FIRST(rs->active.rules);
3264 while ((rule != NULL) && (rule->nr != nr))
3265 rule = TAILQ_NEXT(rule, entries);
3266 if (rule == NULL) {
3267 PF_RULES_RUNLOCK();
3268 ERROUT(ENOENT);
3269 }
3270 /* Make sure rule can't go away. */
3271 NET_EPOCH_ENTER(et);
3272 PF_RULES_RUNLOCK();
3273 nvl = pf_keth_rule_to_nveth_rule(rule);
3274 if (pf_keth_anchor_nvcopyout(rs, rule, nvl)) {
3275 NET_EPOCH_EXIT(et);
3276 ERROUT(EBUSY);
3277 }
3278 NET_EPOCH_EXIT(et);
3279 if (nvl == NULL)
3280 ERROUT(ENOMEM);
3281
3282 nvlpacked = nvlist_pack(nvl, &nv->len);
3283 if (nvlpacked == NULL)
3284 ERROUT(ENOMEM);
3285
3286 if (nv->size == 0)
3287 ERROUT(0);
3288 else if (nv->size < nv->len)
3289 ERROUT(ENOSPC);
3290
3291 error = copyout(nvlpacked, nv->data, nv->len);
3292 if (error == 0 && clear) {
3293 counter_u64_zero(rule->evaluations);
3294 for (int i = 0; i < 2; i++) {
3295 counter_u64_zero(rule->packets[i]);
3296 counter_u64_zero(rule->bytes[i]);
3297 }
3298 }
3299
3300 #undef ERROUT
3301 DIOCGETETHRULE_error:
3302 free(nvlpacked, M_NVLIST);
3303 nvlist_destroy(nvl);
3304 break;
3305 }
3306
3307 case DIOCADDETHRULE: {
3308 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
3309 nvlist_t *nvl = NULL;
3310 void *nvlpacked = NULL;
3311 struct pf_keth_rule *rule = NULL, *tail = NULL;
3312 struct pf_keth_ruleset *ruleset = NULL;
3313 struct pfi_kkif *kif = NULL, *bridge_to_kif = NULL;
3314 const char *anchor = "", *anchor_call = "";
3315
3316 #define ERROUT(x) ERROUT_IOCTL(DIOCADDETHRULE_error, x)
3317
3318 if (nv->len > pf_ioctl_maxcount)
3319 ERROUT(ENOMEM);
3320
3321 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3322 error = copyin(nv->data, nvlpacked, nv->len);
3323 if (error)
3324 ERROUT(error);
3325
3326 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3327 if (nvl == NULL)
3328 ERROUT(EBADMSG);
3329
3330 if (! nvlist_exists_number(nvl, "ticket"))
3331 ERROUT(EBADMSG);
3332
3333 if (nvlist_exists_string(nvl, "anchor"))
3334 anchor = nvlist_get_string(nvl, "anchor");
3335 if (nvlist_exists_string(nvl, "anchor_call"))
3336 anchor_call = nvlist_get_string(nvl, "anchor_call");
3337
3338 ruleset = pf_find_keth_ruleset(anchor);
3339 if (ruleset == NULL)
3340 ERROUT(EINVAL);
3341
3342 if (nvlist_get_number(nvl, "ticket") !=
3343 ruleset->inactive.ticket) {
3344 DPFPRINTF(PF_DEBUG_MISC,
3345 "ticket: %d != %d",
3346 (u_int32_t)nvlist_get_number(nvl, "ticket"),
3347 ruleset->inactive.ticket);
3348 ERROUT(EBUSY);
3349 }
3350
3351 rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK);
3352 rule->timestamp = NULL;
3353
3354 error = pf_nveth_rule_to_keth_rule(nvl, rule);
3355 if (error != 0)
3356 ERROUT(error);
3357
3358 if (rule->ifname[0])
3359 kif = pf_kkif_create(M_WAITOK);
3360 if (rule->bridge_to_name[0])
3361 bridge_to_kif = pf_kkif_create(M_WAITOK);
3362 rule->evaluations = counter_u64_alloc(M_WAITOK);
3363 for (int i = 0; i < 2; i++) {
3364 rule->packets[i] = counter_u64_alloc(M_WAITOK);
3365 rule->bytes[i] = counter_u64_alloc(M_WAITOK);
3366 }
3367 rule->timestamp = uma_zalloc_pcpu(pf_timestamp_pcpu_zone,
3368 M_WAITOK | M_ZERO);
3369
3370 PF_RULES_WLOCK();
3371
3372 if (rule->ifname[0]) {
3373 rule->kif = pfi_kkif_attach(kif, rule->ifname);
3374 pfi_kkif_ref(rule->kif);
3375 } else
3376 rule->kif = NULL;
3377 if (rule->bridge_to_name[0]) {
3378 rule->bridge_to = pfi_kkif_attach(bridge_to_kif,
3379 rule->bridge_to_name);
3380 pfi_kkif_ref(rule->bridge_to);
3381 } else
3382 rule->bridge_to = NULL;
3383
3384 #ifdef ALTQ
3385 /* set queue IDs */
3386 if (rule->qname[0] != 0) {
3387 if ((rule->qid = pf_qname2qid(rule->qname, true)) == 0)
3388 error = EBUSY;
3389 else
3390 rule->qid = rule->qid;
3391 }
3392 #endif
3393 if (rule->tagname[0])
3394 if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
3395 error = EBUSY;
3396 if (rule->match_tagname[0])
3397 if ((rule->match_tag = pf_tagname2tag(
3398 rule->match_tagname)) == 0)
3399 error = EBUSY;
3400
3401 if (error == 0 && rule->ipdst.addr.type == PF_ADDR_TABLE)
3402 error = pf_eth_addr_setup(ruleset, &rule->ipdst.addr);
3403 if (error == 0 && rule->ipsrc.addr.type == PF_ADDR_TABLE)
3404 error = pf_eth_addr_setup(ruleset, &rule->ipsrc.addr);
3405
3406 if (error) {
3407 pf_free_eth_rule(rule);
3408 PF_RULES_WUNLOCK();
3409 ERROUT(error);
3410 }
3411
3412 if (pf_keth_anchor_setup(rule, ruleset, anchor_call)) {
3413 pf_free_eth_rule(rule);
3414 PF_RULES_WUNLOCK();
3415 ERROUT(EINVAL);
3416 }
3417
3418 tail = TAILQ_LAST(ruleset->inactive.rules, pf_keth_ruleq);
3419 if (tail)
3420 rule->nr = tail->nr + 1;
3421 else
3422 rule->nr = 0;
3423
3424 TAILQ_INSERT_TAIL(ruleset->inactive.rules, rule, entries);
3425
3426 PF_RULES_WUNLOCK();
3427
3428 #undef ERROUT
3429 DIOCADDETHRULE_error:
3430 nvlist_destroy(nvl);
3431 free(nvlpacked, M_NVLIST);
3432 break;
3433 }
3434
3435 case DIOCGETETHRULESETS: {
3436 struct epoch_tracker et;
3437 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
3438 nvlist_t *nvl = NULL;
3439 void *nvlpacked = NULL;
3440 struct pf_keth_ruleset *ruleset;
3441 struct pf_keth_anchor *anchor;
3442 int nr = 0;
3443
3444 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULESETS_error, x)
3445
3446 if (nv->len > pf_ioctl_maxcount)
3447 ERROUT(ENOMEM);
3448
3449 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3450 error = copyin(nv->data, nvlpacked, nv->len);
3451 if (error)
3452 ERROUT(error);
3453
3454 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3455 if (nvl == NULL)
3456 ERROUT(EBADMSG);
3457 if (! nvlist_exists_string(nvl, "path"))
3458 ERROUT(EBADMSG);
3459
3460 NET_EPOCH_ENTER(et);
3461
3462 if ((ruleset = pf_find_keth_ruleset(
3463 nvlist_get_string(nvl, "path"))) == NULL) {
3464 NET_EPOCH_EXIT(et);
3465 ERROUT(ENOENT);
3466 }
3467
3468 if (ruleset->anchor == NULL) {
3469 RB_FOREACH(anchor, pf_keth_anchor_global, &V_pf_keth_anchors)
3470 if (anchor->parent == NULL)
3471 nr++;
3472 } else {
3473 RB_FOREACH(anchor, pf_keth_anchor_node,
3474 &ruleset->anchor->children)
3475 nr++;
3476 }
3477
3478 NET_EPOCH_EXIT(et);
3479
3480 nvlist_destroy(nvl);
3481 nvl = NULL;
3482 free(nvlpacked, M_NVLIST);
3483 nvlpacked = NULL;
3484
3485 nvl = nvlist_create(0);
3486 if (nvl == NULL)
3487 ERROUT(ENOMEM);
3488
3489 nvlist_add_number(nvl, "nr", nr);
3490
3491 nvlpacked = nvlist_pack(nvl, &nv->len);
3492 if (nvlpacked == NULL)
3493 ERROUT(ENOMEM);
3494
3495 if (nv->size == 0)
3496 ERROUT(0);
3497 else if (nv->size < nv->len)
3498 ERROUT(ENOSPC);
3499
3500 error = copyout(nvlpacked, nv->data, nv->len);
3501
3502 #undef ERROUT
3503 DIOCGETETHRULESETS_error:
3504 free(nvlpacked, M_NVLIST);
3505 nvlist_destroy(nvl);
3506 break;
3507 }
3508
3509 case DIOCGETETHRULESET: {
3510 struct epoch_tracker et;
3511 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
3512 nvlist_t *nvl = NULL;
3513 void *nvlpacked = NULL;
3514 struct pf_keth_ruleset *ruleset;
3515 struct pf_keth_anchor *anchor;
3516 int nr = 0, req_nr = 0;
3517 bool found = false;
3518
3519 #define ERROUT(x) ERROUT_IOCTL(DIOCGETETHRULESET_error, x)
3520
3521 if (nv->len > pf_ioctl_maxcount)
3522 ERROUT(ENOMEM);
3523
3524 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3525 error = copyin(nv->data, nvlpacked, nv->len);
3526 if (error)
3527 ERROUT(error);
3528
3529 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3530 if (nvl == NULL)
3531 ERROUT(EBADMSG);
3532 if (! nvlist_exists_string(nvl, "path"))
3533 ERROUT(EBADMSG);
3534 if (! nvlist_exists_number(nvl, "nr"))
3535 ERROUT(EBADMSG);
3536
3537 req_nr = nvlist_get_number(nvl, "nr");
3538
3539 NET_EPOCH_ENTER(et);
3540
3541 if ((ruleset = pf_find_keth_ruleset(
3542 nvlist_get_string(nvl, "path"))) == NULL) {
3543 NET_EPOCH_EXIT(et);
3544 ERROUT(ENOENT);
3545 }
3546
3547 nvlist_destroy(nvl);
3548 nvl = NULL;
3549 free(nvlpacked, M_NVLIST);
3550 nvlpacked = NULL;
3551
3552 nvl = nvlist_create(0);
3553 if (nvl == NULL) {
3554 NET_EPOCH_EXIT(et);
3555 ERROUT(ENOMEM);
3556 }
3557
3558 if (ruleset->anchor == NULL) {
3559 RB_FOREACH(anchor, pf_keth_anchor_global,
3560 &V_pf_keth_anchors) {
3561 if (anchor->parent == NULL && nr++ == req_nr) {
3562 found = true;
3563 break;
3564 }
3565 }
3566 } else {
3567 RB_FOREACH(anchor, pf_keth_anchor_node,
3568 &ruleset->anchor->children) {
3569 if (nr++ == req_nr) {
3570 found = true;
3571 break;
3572 }
3573 }
3574 }
3575
3576 NET_EPOCH_EXIT(et);
3577 if (found) {
3578 nvlist_add_number(nvl, "nr", nr);
3579 nvlist_add_string(nvl, "name", anchor->name);
3580 if (ruleset->anchor)
3581 nvlist_add_string(nvl, "path",
3582 ruleset->anchor->path);
3583 else
3584 nvlist_add_string(nvl, "path", "");
3585 } else {
3586 ERROUT(EBUSY);
3587 }
3588
3589 nvlpacked = nvlist_pack(nvl, &nv->len);
3590 if (nvlpacked == NULL)
3591 ERROUT(ENOMEM);
3592
3593 if (nv->size == 0)
3594 ERROUT(0);
3595 else if (nv->size < nv->len)
3596 ERROUT(ENOSPC);
3597
3598 error = copyout(nvlpacked, nv->data, nv->len);
3599
3600 #undef ERROUT
3601 DIOCGETETHRULESET_error:
3602 free(nvlpacked, M_NVLIST);
3603 nvlist_destroy(nvl);
3604 break;
3605 }
3606
3607 case DIOCADDRULENV: {
3608 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
3609 nvlist_t *nvl = NULL;
3610 void *nvlpacked = NULL;
3611 struct pf_krule *rule = NULL;
3612 const char *anchor = "", *anchor_call = "";
3613 uint32_t ticket = 0, pool_ticket = 0;
3614
3615 #define ERROUT(x) ERROUT_IOCTL(DIOCADDRULENV_error, x)
3616
3617 if (nv->len > pf_ioctl_maxcount)
3618 ERROUT(ENOMEM);
3619
3620 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3621 error = copyin(nv->data, nvlpacked, nv->len);
3622 if (error)
3623 ERROUT(error);
3624
3625 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3626 if (nvl == NULL)
3627 ERROUT(EBADMSG);
3628
3629 if (! nvlist_exists_number(nvl, "ticket"))
3630 ERROUT(EINVAL);
3631 ticket = nvlist_get_number(nvl, "ticket");
3632
3633 if (! nvlist_exists_number(nvl, "pool_ticket"))
3634 ERROUT(EINVAL);
3635 pool_ticket = nvlist_get_number(nvl, "pool_ticket");
3636
3637 if (! nvlist_exists_nvlist(nvl, "rule"))
3638 ERROUT(EINVAL);
3639
3640 rule = pf_krule_alloc();
3641 error = pf_nvrule_to_krule(nvlist_get_nvlist(nvl, "rule"),
3642 rule);
3643 if (error)
3644 ERROUT(error);
3645
3646 if (nvlist_exists_string(nvl, "anchor"))
3647 anchor = nvlist_get_string(nvl, "anchor");
3648 if (nvlist_exists_string(nvl, "anchor_call"))
3649 anchor_call = nvlist_get_string(nvl, "anchor_call");
3650
3651 if ((error = nvlist_error(nvl)))
3652 ERROUT(error);
3653
3654 /* Frees rule on error */
3655 error = pf_ioctl_addrule(rule, ticket, pool_ticket, anchor,
3656 anchor_call, td->td_ucred->cr_ruid,
3657 td->td_proc ? td->td_proc->p_pid : 0);
3658
3659 nvlist_destroy(nvl);
3660 free(nvlpacked, M_NVLIST);
3661 break;
3662 #undef ERROUT
3663 DIOCADDRULENV_error:
3664 pf_krule_free(rule);
3665 nvlist_destroy(nvl);
3666 free(nvlpacked, M_NVLIST);
3667
3668 break;
3669 }
3670 case DIOCADDRULE: {
3671 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
3672 struct pf_krule *rule;
3673
3674 rule = pf_krule_alloc();
3675 error = pf_rule_to_krule(&pr->rule, rule);
3676 if (error != 0) {
3677 pf_krule_free(rule);
3678 goto fail;
3679 }
3680
3681 pr->anchor[sizeof(pr->anchor) - 1] = '\0';
3682
3683 /* Frees rule on error */
3684 error = pf_ioctl_addrule(rule, pr->ticket, pr->pool_ticket,
3685 pr->anchor, pr->anchor_call, td->td_ucred->cr_ruid,
3686 td->td_proc ? td->td_proc->p_pid : 0);
3687 break;
3688 }
3689
3690 case DIOCGETRULES: {
3691 struct pfioc_rule *pr = (struct pfioc_rule *)addr;
3692
3693 pr->anchor[sizeof(pr->anchor) - 1] = '\0';
3694
3695 error = pf_ioctl_getrules(pr);
3696
3697 break;
3698 }
3699
3700 case DIOCGETRULENV: {
3701 struct pfioc_nv *nv = (struct pfioc_nv *)addr;
3702 nvlist_t *nvrule = NULL;
3703 nvlist_t *nvl = NULL;
3704 struct pf_kruleset *ruleset;
3705 struct pf_krule *rule;
3706 void *nvlpacked = NULL;
3707 int rs_num, nr;
3708 bool clear_counter = false;
3709
3710 #define ERROUT(x) ERROUT_IOCTL(DIOCGETRULENV_error, x)
3711
3712 if (nv->len > pf_ioctl_maxcount)
3713 ERROUT(ENOMEM);
3714
3715 /* Copy the request in */
3716 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
3717 error = copyin(nv->data, nvlpacked, nv->len);
3718 if (error)
3719 ERROUT(error);
3720
3721 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
3722 if (nvl == NULL)
3723 ERROUT(EBADMSG);
3724
3725 if (! nvlist_exists_string(nvl, "anchor"))
3726 ERROUT(EBADMSG);
3727 if (! nvlist_exists_number(nvl, "ruleset"))
3728 ERROUT(EBADMSG);
3729 if (! nvlist_exists_number(nvl, "ticket"))
3730 ERROUT(EBADMSG);
3731 if (! nvlist_exists_number(nvl, "nr"))
3732 ERROUT(EBADMSG);
3733
3734 if (nvlist_exists_bool(nvl, "clear_counter"))
3735 clear_counter = nvlist_get_bool(nvl, "clear_counter");
3736
3737 if (clear_counter && !(flags & FWRITE))
3738 ERROUT(EACCES);
3739
3740 nr = nvlist_get_number(nvl, "nr");
3741
3742 PF_RULES_WLOCK();
3743 ruleset = pf_find_kruleset(nvlist_get_string(nvl, "anchor"));
3744 if (ruleset == NULL) {
3745 PF_RULES_WUNLOCK();
3746 ERROUT(ENOENT);
3747 }
3748
3749 rs_num = pf_get_ruleset_number(nvlist_get_number(nvl, "ruleset"));
3750 if (rs_num >= PF_RULESET_MAX) {
3751 PF_RULES_WUNLOCK();
3752 ERROUT(EINVAL);
3753 }
3754
3755 if (nvlist_get_number(nvl, "ticket") !=
3756 ruleset->rules[rs_num].active.ticket) {
3757 PF_RULES_WUNLOCK();
3758 ERROUT(EBUSY);
3759 }
3760
3761 if ((error = nvlist_error(nvl))) {
3762 PF_RULES_WUNLOCK();
3763 ERROUT(error);
3764 }
3765
3766 rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
3767 while ((rule != NULL) && (rule->nr != nr))
3768 rule = TAILQ_NEXT(rule, entries);
3769 if (rule == NULL) {
3770 PF_RULES_WUNLOCK();
3771 ERROUT(EBUSY);
3772 }
3773
3774 nvrule = pf_krule_to_nvrule(rule);
3775
3776 nvlist_destroy(nvl);
3777 nvl = nvlist_create(0);
3778 if (nvl == NULL) {
3779 PF_RULES_WUNLOCK();
3780 ERROUT(ENOMEM);
3781 }
3782 nvlist_add_number(nvl, "nr", nr);
3783 nvlist_add_nvlist(nvl, "rule", nvrule);
3784 nvlist_destroy(nvrule);
3785 nvrule = NULL;
3786 if (pf_kanchor_nvcopyout(ruleset, rule, nvl)) {
3787 PF_RULES_WUNLOCK();
3788 ERROUT(EBUSY);
3789 }
3790
3791 free(nvlpacked, M_NVLIST);
3792 nvlpacked = nvlist_pack(nvl, &nv->len);
3793 if (nvlpacked == NULL) {
3794 PF_RULES_WUNLOCK();
3795 ERROUT(ENOMEM);
3796 }
3797
3798 if (nv->size == 0) {
3799 PF_RULES_WUNLOCK();
3800 ERROUT(0);
3801 }
3802 else if (nv->size < nv->len) {
3803 PF_RULES_WUNLOCK();
3804 ERROUT(ENOSPC);
3805 }
3806
3807 if (clear_counter)
3808 pf_krule_clear_counters(rule);
3809
3810 PF_RULES_WUNLOCK();
3811
3812 error = copyout(nvlpacked, nv->data, nv->len);
3813
3814 #undef ERROUT
3815 DIOCGETRULENV_error:
3816 free(nvlpacked, M_NVLIST);
3817 nvlist_destroy(nvrule);
3818 nvlist_destroy(nvl);
3819
3820 break;
3821 }
3822
3823 case DIOCCHANGERULE: {
3824 struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
3825 struct pf_kruleset *ruleset;
3826 struct pf_krule *oldrule = NULL, *newrule = NULL;
3827 struct pfi_kkif *kif = NULL;
3828 struct pf_kpooladdr *pa;
3829 u_int32_t nr = 0;
3830 int rs_num;
3831
3832 pcr->anchor[sizeof(pcr->anchor) - 1] = '\0';
3833
3834 if (pcr->action < PF_CHANGE_ADD_HEAD ||
3835 pcr->action > PF_CHANGE_GET_TICKET) {
3836 error = EINVAL;
3837 goto fail;
3838 }
3839 if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
3840 error = EINVAL;
3841 goto fail;
3842 }
3843
3844 if (pcr->action != PF_CHANGE_REMOVE) {
3845 newrule = pf_krule_alloc();
3846 error = pf_rule_to_krule(&pcr->rule, newrule);
3847 if (error != 0) {
3848 pf_krule_free(newrule);
3849 goto fail;
3850 }
3851
3852 if ((error = pf_rule_checkaf(newrule))) {
3853 pf_krule_free(newrule);
3854 goto fail;
3855 }
3856 if (newrule->ifname[0])
3857 kif = pf_kkif_create(M_WAITOK);
3858 pf_counter_u64_init(&newrule->evaluations, M_WAITOK);
3859 for (int i = 0; i < 2; i++) {
3860 pf_counter_u64_init(&newrule->packets[i], M_WAITOK);
3861 pf_counter_u64_init(&newrule->bytes[i], M_WAITOK);
3862 }
3863 newrule->states_cur = counter_u64_alloc(M_WAITOK);
3864 newrule->states_tot = counter_u64_alloc(M_WAITOK);
3865 for (pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; sn_type++)
3866 newrule->src_nodes[sn_type] = counter_u64_alloc(M_WAITOK);
3867 newrule->cuid = td->td_ucred->cr_ruid;
3868 newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
3869 TAILQ_INIT(&newrule->nat.list);
3870 TAILQ_INIT(&newrule->rdr.list);
3871 TAILQ_INIT(&newrule->route.list);
3872 }
3873 #define ERROUT(x) ERROUT_IOCTL(DIOCCHANGERULE_error, x)
3874
3875 PF_CONFIG_LOCK();
3876 PF_RULES_WLOCK();
3877 #ifdef PF_WANT_32_TO_64_COUNTER
3878 if (newrule != NULL) {
3879 LIST_INSERT_HEAD(&V_pf_allrulelist, newrule, allrulelist);
3880 newrule->allrulelinked = true;
3881 V_pf_allrulecount++;
3882 }
3883 #endif
3884
3885 if (!(pcr->action == PF_CHANGE_REMOVE ||
3886 pcr->action == PF_CHANGE_GET_TICKET) &&
3887 pcr->pool_ticket != V_ticket_pabuf)
3888 ERROUT(EBUSY);
3889
3890 ruleset = pf_find_kruleset(pcr->anchor);
3891 if (ruleset == NULL)
3892 ERROUT(EINVAL);
3893
3894 rs_num = pf_get_ruleset_number(pcr->rule.action);
3895 if (rs_num >= PF_RULESET_MAX)
3896 ERROUT(EINVAL);
3897
3898 /*
3899 * XXXMJG: there is no guarantee that the ruleset was
3900 * created by the usual route of calling DIOCXBEGIN.
3901 * As a result it is possible the rule tree will not
3902 * be allocated yet. Hack around it by doing it here.
3903 * Note it is fine to let the tree persist in case of
3904 * error as it will be freed down the road on future
3905 * updates (if need be).
3906 */
3907 if (ruleset->rules[rs_num].active.tree == NULL) {
3908 ruleset->rules[rs_num].active.tree = pf_rule_tree_alloc(M_NOWAIT);
3909 if (ruleset->rules[rs_num].active.tree == NULL) {
3910 ERROUT(ENOMEM);
3911 }
3912 }
3913
3914 if (pcr->action == PF_CHANGE_GET_TICKET) {
3915 pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
3916 ERROUT(0);
3917 } else if (pcr->ticket !=
3918 ruleset->rules[rs_num].active.ticket)
3919 ERROUT(EINVAL);
3920
3921 if (pcr->action != PF_CHANGE_REMOVE) {
3922 if (newrule->ifname[0]) {
3923 newrule->kif = pfi_kkif_attach(kif,
3924 newrule->ifname);
3925 kif = NULL;
3926 pfi_kkif_ref(newrule->kif);
3927 } else
3928 newrule->kif = NULL;
3929
3930 if (newrule->rtableid > 0 &&
3931 newrule->rtableid >= rt_numfibs)
3932 error = EBUSY;
3933
3934 #ifdef ALTQ
3935 /* set queue IDs */
3936 if (newrule->qname[0] != 0) {
3937 if ((newrule->qid =
3938 pf_qname2qid(newrule->qname, true)) == 0)
3939 error = EBUSY;
3940 else if (newrule->pqname[0] != 0) {
3941 if ((newrule->pqid =
3942 pf_qname2qid(newrule->pqname, true)) == 0)
3943 error = EBUSY;
3944 } else
3945 newrule->pqid = newrule->qid;
3946 }
3947 #endif /* ALTQ */
3948 if (newrule->tagname[0])
3949 if ((newrule->tag =
3950 pf_tagname2tag(newrule->tagname)) == 0)
3951 error = EBUSY;
3952 if (newrule->match_tagname[0])
3953 if ((newrule->match_tag = pf_tagname2tag(
3954 newrule->match_tagname)) == 0)
3955 error = EBUSY;
3956 if (newrule->rt && !newrule->direction)
3957 error = EINVAL;
3958 if (!newrule->log)
3959 newrule->logif = 0;
3960 if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af))
3961 error = ENOMEM;
3962 if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af))
3963 error = ENOMEM;
3964 if (pf_kanchor_setup(newrule, ruleset, pcr->anchor_call))
3965 error = EINVAL;
3966 for (int i = 0; i < 3; i++) {
3967 TAILQ_FOREACH(pa, &V_pf_pabuf[i], entries)
3968 if (pa->addr.type == PF_ADDR_TABLE) {
3969 pa->addr.p.tbl =
3970 pfr_attach_table(ruleset,
3971 pa->addr.v.tblname);
3972 if (pa->addr.p.tbl == NULL)
3973 error = ENOMEM;
3974 }
3975 }
3976
3977 newrule->overload_tbl = NULL;
3978 if (newrule->overload_tblname[0]) {
3979 if ((newrule->overload_tbl = pfr_attach_table(
3980 ruleset, newrule->overload_tblname)) ==
3981 NULL)
3982 error = EINVAL;
3983 else
3984 newrule->overload_tbl->pfrkt_flags |=
3985 PFR_TFLAG_ACTIVE;
3986 }
3987
3988 pf_mv_kpool(&V_pf_pabuf[0], &newrule->nat.list);
3989 pf_mv_kpool(&V_pf_pabuf[1], &newrule->rdr.list);
3990 pf_mv_kpool(&V_pf_pabuf[2], &newrule->route.list);
3991 if (((((newrule->action == PF_NAT) ||
3992 (newrule->action == PF_RDR) ||
3993 (newrule->action == PF_BINAT) ||
3994 (newrule->rt > PF_NOPFROUTE)) &&
3995 !newrule->anchor)) &&
3996 (TAILQ_FIRST(&newrule->rdr.list) == NULL))
3997 error = EINVAL;
3998
3999 if (error) {
4000 pf_free_rule(newrule);
4001 PF_RULES_WUNLOCK();
4002 PF_CONFIG_UNLOCK();
4003 goto fail;
4004 }
4005
4006 newrule->nat.cur = TAILQ_FIRST(&newrule->nat.list);
4007 newrule->rdr.cur = TAILQ_FIRST(&newrule->rdr.list);
4008 }
4009 pf_empty_kpool(&V_pf_pabuf[0]);
4010 pf_empty_kpool(&V_pf_pabuf[1]);
4011 pf_empty_kpool(&V_pf_pabuf[2]);
4012
4013 if (pcr->action == PF_CHANGE_ADD_HEAD)
4014 oldrule = TAILQ_FIRST(
4015 ruleset->rules[rs_num].active.ptr);
4016 else if (pcr->action == PF_CHANGE_ADD_TAIL)
4017 oldrule = TAILQ_LAST(
4018 ruleset->rules[rs_num].active.ptr, pf_krulequeue);
4019 else {
4020 oldrule = TAILQ_FIRST(
4021 ruleset->rules[rs_num].active.ptr);
4022 while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
4023 oldrule = TAILQ_NEXT(oldrule, entries);
4024 if (oldrule == NULL) {
4025 if (newrule != NULL)
4026 pf_free_rule(newrule);
4027 PF_RULES_WUNLOCK();
4028 PF_CONFIG_UNLOCK();
4029 error = EINVAL;
4030 goto fail;
4031 }
4032 }
4033
4034 if (pcr->action == PF_CHANGE_REMOVE) {
4035 pf_unlink_rule(ruleset->rules[rs_num].active.ptr,
4036 oldrule);
4037 RB_REMOVE(pf_krule_global,
4038 ruleset->rules[rs_num].active.tree, oldrule);
4039 ruleset->rules[rs_num].active.rcount--;
4040 } else {
4041 pf_hash_rule(newrule);
4042 if (RB_INSERT(pf_krule_global,
4043 ruleset->rules[rs_num].active.tree, newrule) != NULL) {
4044 pf_free_rule(newrule);
4045 PF_RULES_WUNLOCK();
4046 PF_CONFIG_UNLOCK();
4047 error = EEXIST;
4048 goto fail;
4049 }
4050
4051 if (oldrule == NULL)
4052 TAILQ_INSERT_TAIL(
4053 ruleset->rules[rs_num].active.ptr,
4054 newrule, entries);
4055 else if (pcr->action == PF_CHANGE_ADD_HEAD ||
4056 pcr->action == PF_CHANGE_ADD_BEFORE)
4057 TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
4058 else
4059 TAILQ_INSERT_AFTER(
4060 ruleset->rules[rs_num].active.ptr,
4061 oldrule, newrule, entries);
4062 ruleset->rules[rs_num].active.rcount++;
4063 }
4064
4065 nr = 0;
4066 TAILQ_FOREACH(oldrule,
4067 ruleset->rules[rs_num].active.ptr, entries)
4068 oldrule->nr = nr++;
4069
4070 ruleset->rules[rs_num].active.ticket++;
4071
4072 pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
4073 pf_remove_if_empty_kruleset(ruleset);
4074
4075 PF_RULES_WUNLOCK();
4076 PF_CONFIG_UNLOCK();
4077 break;
4078
4079 #undef ERROUT
4080 DIOCCHANGERULE_error:
4081 PF_RULES_WUNLOCK();
4082 PF_CONFIG_UNLOCK();
4083 pf_krule_free(newrule);
4084 pf_kkif_free(kif);
4085 break;
4086 }
4087
4088 case DIOCCLRSTATESNV: {
4089 error = pf_clearstates_nv((struct pfioc_nv *)addr);
4090 break;
4091 }
4092
4093 case DIOCKILLSTATESNV: {
4094 error = pf_killstates_nv((struct pfioc_nv *)addr);
4095 break;
4096 }
4097
4098 case DIOCADDSTATE: {
4099 struct pfioc_state *ps = (struct pfioc_state *)addr;
4100 struct pfsync_state_1301 *sp = &ps->state;
4101
4102 if (sp->timeout >= PFTM_MAX) {
4103 error = EINVAL;
4104 goto fail;
4105 }
4106 if (V_pfsync_state_import_ptr != NULL) {
4107 PF_RULES_RLOCK();
4108 error = V_pfsync_state_import_ptr(
4109 (union pfsync_state_union *)sp, PFSYNC_SI_IOCTL,
4110 PFSYNC_MSG_VERSION_1301);
4111 PF_RULES_RUNLOCK();
4112 } else
4113 error = EOPNOTSUPP;
4114 break;
4115 }
4116
4117 case DIOCGETSTATE: {
4118 struct pfioc_state *ps = (struct pfioc_state *)addr;
4119 struct pf_kstate *s;
4120
4121 s = pf_find_state_byid(ps->state.id, ps->state.creatorid);
4122 if (s == NULL) {
4123 error = ENOENT;
4124 goto fail;
4125 }
4126
4127 pfsync_state_export((union pfsync_state_union*)&ps->state,
4128 s, PFSYNC_MSG_VERSION_1301);
4129 PF_STATE_UNLOCK(s);
4130 break;
4131 }
4132
4133 case DIOCGETSTATENV: {
4134 error = pf_getstate((struct pfioc_nv *)addr);
4135 break;
4136 }
4137
4138 #ifdef COMPAT_FREEBSD14
4139 case DIOCGETSTATES: {
4140 struct pfioc_states *ps = (struct pfioc_states *)addr;
4141 struct pf_kstate *s;
4142 struct pfsync_state_1301 *pstore, *p;
4143 int i, nr;
4144 size_t slice_count = 16, count;
4145 void *out;
4146
4147 if (ps->ps_len <= 0) {
4148 nr = uma_zone_get_cur(V_pf_state_z);
4149 ps->ps_len = sizeof(struct pfsync_state_1301) * nr;
4150 break;
4151 }
4152
4153 out = ps->ps_states;
4154 pstore = mallocarray(slice_count,
4155 sizeof(struct pfsync_state_1301), M_PF, M_WAITOK | M_ZERO);
4156 nr = 0;
4157
4158 for (i = 0; i <= V_pf_hashmask; i++) {
4159 struct pf_idhash *ih = &V_pf_idhash[i];
4160
4161 DIOCGETSTATES_retry:
4162 p = pstore;
4163
4164 if (LIST_EMPTY(&ih->states))
4165 continue;
4166
4167 PF_HASHROW_LOCK(ih);
4168 count = 0;
4169 LIST_FOREACH(s, &ih->states, entry) {
4170 if (s->timeout == PFTM_UNLINKED)
4171 continue;
4172 count++;
4173 }
4174
4175 if (count > slice_count) {
4176 PF_HASHROW_UNLOCK(ih);
4177 free(pstore, M_PF);
4178 slice_count = count * 2;
4179 pstore = mallocarray(slice_count,
4180 sizeof(struct pfsync_state_1301), M_PF,
4181 M_WAITOK | M_ZERO);
4182 goto DIOCGETSTATES_retry;
4183 }
4184
4185 if ((nr+count) * sizeof(*p) > ps->ps_len) {
4186 PF_HASHROW_UNLOCK(ih);
4187 goto DIOCGETSTATES_full;
4188 }
4189
4190 LIST_FOREACH(s, &ih->states, entry) {
4191 if (s->timeout == PFTM_UNLINKED)
4192 continue;
4193
4194 pfsync_state_export((union pfsync_state_union*)p,
4195 s, PFSYNC_MSG_VERSION_1301);
4196 p++;
4197 nr++;
4198 }
4199 PF_HASHROW_UNLOCK(ih);
4200 error = copyout(pstore, out,
4201 sizeof(struct pfsync_state_1301) * count);
4202 if (error) {
4203 free(pstore, M_PF);
4204 goto fail;
4205 }
4206 out = ps->ps_states + nr;
4207 }
4208 DIOCGETSTATES_full:
4209 ps->ps_len = sizeof(struct pfsync_state_1301) * nr;
4210 free(pstore, M_PF);
4211
4212 break;
4213 }
4214
4215 case DIOCGETSTATESV2: {
4216 struct pfioc_states_v2 *ps = (struct pfioc_states_v2 *)addr;
4217 struct pf_kstate *s;
4218 struct pf_state_export *pstore, *p;
4219 int i, nr;
4220 size_t slice_count = 16, count;
4221 void *out;
4222
4223 if (ps->ps_req_version > PF_STATE_VERSION) {
4224 error = ENOTSUP;
4225 goto fail;
4226 }
4227
4228 if (ps->ps_len <= 0) {
4229 nr = uma_zone_get_cur(V_pf_state_z);
4230 ps->ps_len = sizeof(struct pf_state_export) * nr;
4231 break;
4232 }
4233
4234 out = ps->ps_states;
4235 pstore = mallocarray(slice_count,
4236 sizeof(struct pf_state_export), M_PF, M_WAITOK | M_ZERO);
4237 nr = 0;
4238
4239 for (i = 0; i <= V_pf_hashmask; i++) {
4240 struct pf_idhash *ih = &V_pf_idhash[i];
4241
4242 DIOCGETSTATESV2_retry:
4243 p = pstore;
4244
4245 if (LIST_EMPTY(&ih->states))
4246 continue;
4247
4248 PF_HASHROW_LOCK(ih);
4249 count = 0;
4250 LIST_FOREACH(s, &ih->states, entry) {
4251 if (s->timeout == PFTM_UNLINKED)
4252 continue;
4253 count++;
4254 }
4255
4256 if (count > slice_count) {
4257 PF_HASHROW_UNLOCK(ih);
4258 free(pstore, M_PF);
4259 slice_count = count * 2;
4260 pstore = mallocarray(slice_count,
4261 sizeof(struct pf_state_export), M_PF,
4262 M_WAITOK | M_ZERO);
4263 goto DIOCGETSTATESV2_retry;
4264 }
4265
4266 if ((nr+count) * sizeof(*p) > ps->ps_len) {
4267 PF_HASHROW_UNLOCK(ih);
4268 goto DIOCGETSTATESV2_full;
4269 }
4270
4271 LIST_FOREACH(s, &ih->states, entry) {
4272 if (s->timeout == PFTM_UNLINKED)
4273 continue;
4274
4275 pf_state_export(p, s);
4276 p++;
4277 nr++;
4278 }
4279 PF_HASHROW_UNLOCK(ih);
4280 error = copyout(pstore, out,
4281 sizeof(struct pf_state_export) * count);
4282 if (error) {
4283 free(pstore, M_PF);
4284 goto fail;
4285 }
4286 out = ps->ps_states + nr;
4287 }
4288 DIOCGETSTATESV2_full:
4289 ps->ps_len = nr * sizeof(struct pf_state_export);
4290 free(pstore, M_PF);
4291
4292 break;
4293 }
4294 #endif
4295 case DIOCGETSTATUSNV: {
4296 error = pf_getstatus((struct pfioc_nv *)addr);
4297 break;
4298 }
4299
4300 case DIOCSETSTATUSIF: {
4301 struct pfioc_if *pi = (struct pfioc_if *)addr;
4302
4303 if (pi->ifname[0] == 0) {
4304 bzero(V_pf_status.ifname, IFNAMSIZ);
4305 break;
4306 }
4307 PF_RULES_WLOCK();
4308 error = pf_user_strcpy(V_pf_status.ifname, pi->ifname, IFNAMSIZ);
4309 PF_RULES_WUNLOCK();
4310 break;
4311 }
4312
4313 case DIOCCLRSTATUS: {
4314 pf_ioctl_clear_status();
4315 break;
4316 }
4317
4318 case DIOCNATLOOK: {
4319 struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr;
4320
4321 error = pf_ioctl_natlook(pnl);
4322 break;
4323 }
4324
4325 case DIOCSETTIMEOUT: {
4326 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
4327
4328 error = pf_ioctl_set_timeout(pt->timeout, pt->seconds,
4329 &pt->seconds);
4330 break;
4331 }
4332
4333 case DIOCGETTIMEOUT: {
4334 struct pfioc_tm *pt = (struct pfioc_tm *)addr;
4335
4336 error = pf_ioctl_get_timeout(pt->timeout, &pt->seconds);
4337 break;
4338 }
4339
4340 case DIOCGETLIMIT: {
4341 struct pfioc_limit *pl = (struct pfioc_limit *)addr;
4342
4343 error = pf_ioctl_get_limit(pl->index, &pl->limit);
4344 break;
4345 }
4346
4347 case DIOCSETLIMIT: {
4348 struct pfioc_limit *pl = (struct pfioc_limit *)addr;
4349 unsigned int old_limit;
4350
4351 error = pf_ioctl_set_limit(pl->index, pl->limit, &old_limit);
4352 pl->limit = old_limit;
4353 break;
4354 }
4355
4356 case DIOCSETDEBUG: {
4357 u_int32_t *level = (u_int32_t *)addr;
4358
4359 PF_RULES_WLOCK();
4360 V_pf_status.debug = *level;
4361 PF_RULES_WUNLOCK();
4362 break;
4363 }
4364
4365 case DIOCCLRRULECTRS: {
4366 /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
4367 struct pf_kruleset *ruleset = &pf_main_ruleset;
4368 struct pf_krule *rule;
4369
4370 PF_RULES_WLOCK();
4371 TAILQ_FOREACH(rule,
4372 ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) {
4373 pf_counter_u64_zero(&rule->evaluations);
4374 for (int i = 0; i < 2; i++) {
4375 pf_counter_u64_zero(&rule->packets[i]);
4376 pf_counter_u64_zero(&rule->bytes[i]);
4377 }
4378 }
4379 PF_RULES_WUNLOCK();
4380 break;
4381 }
4382
4383 case DIOCGIFSPEEDV0:
4384 case DIOCGIFSPEEDV1: {
4385 struct pf_ifspeed_v1 *psp = (struct pf_ifspeed_v1 *)addr;
4386 struct pf_ifspeed_v1 ps;
4387 struct ifnet *ifp;
4388
4389 if (psp->ifname[0] == '\0') {
4390 error = EINVAL;
4391 goto fail;
4392 }
4393
4394 error = pf_user_strcpy(ps.ifname, psp->ifname, IFNAMSIZ);
4395 if (error != 0)
4396 goto fail;
4397 ifp = ifunit(ps.ifname);
4398 if (ifp != NULL) {
4399 psp->baudrate32 =
4400 (u_int32_t)uqmin(ifp->if_baudrate, UINT_MAX);
4401 if (cmd == DIOCGIFSPEEDV1)
4402 psp->baudrate = ifp->if_baudrate;
4403 } else {
4404 error = EINVAL;
4405 }
4406 break;
4407 }
4408
4409 #ifdef ALTQ
4410 case DIOCSTARTALTQ: {
4411 struct pf_altq *altq;
4412
4413 PF_RULES_WLOCK();
4414 /* enable all altq interfaces on active list */
4415 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
4416 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
4417 error = pf_enable_altq(altq);
4418 if (error != 0)
4419 break;
4420 }
4421 }
4422 if (error == 0)
4423 V_pf_altq_running = 1;
4424 PF_RULES_WUNLOCK();
4425 DPFPRINTF(PF_DEBUG_MISC, "altq: started");
4426 break;
4427 }
4428
4429 case DIOCSTOPALTQ: {
4430 struct pf_altq *altq;
4431
4432 PF_RULES_WLOCK();
4433 /* disable all altq interfaces on active list */
4434 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries) {
4435 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
4436 error = pf_disable_altq(altq);
4437 if (error != 0)
4438 break;
4439 }
4440 }
4441 if (error == 0)
4442 V_pf_altq_running = 0;
4443 PF_RULES_WUNLOCK();
4444 DPFPRINTF(PF_DEBUG_MISC, "altq: stopped");
4445 break;
4446 }
4447
4448 case DIOCADDALTQV0:
4449 case DIOCADDALTQV1: {
4450 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
4451 struct pf_altq *altq, *a;
4452 struct ifnet *ifp;
4453
4454 altq = malloc(sizeof(*altq), M_PFALTQ, M_WAITOK | M_ZERO);
4455 error = pf_import_kaltq(pa, altq, IOCPARM_LEN(cmd));
4456 if (error)
4457 goto fail;
4458 altq->local_flags = 0;
4459
4460 PF_RULES_WLOCK();
4461 if (pa->ticket != V_ticket_altqs_inactive) {
4462 PF_RULES_WUNLOCK();
4463 free(altq, M_PFALTQ);
4464 error = EBUSY;
4465 goto fail;
4466 }
4467
4468 /*
4469 * if this is for a queue, find the discipline and
4470 * copy the necessary fields
4471 */
4472 if (altq->qname[0] != 0) {
4473 if ((altq->qid = pf_qname2qid(altq->qname, true)) == 0) {
4474 PF_RULES_WUNLOCK();
4475 error = EBUSY;
4476 free(altq, M_PFALTQ);
4477 goto fail;
4478 }
4479 altq->altq_disc = NULL;
4480 TAILQ_FOREACH(a, V_pf_altq_ifs_inactive, entries) {
4481 if (strncmp(a->ifname, altq->ifname,
4482 IFNAMSIZ) == 0) {
4483 altq->altq_disc = a->altq_disc;
4484 break;
4485 }
4486 }
4487 }
4488
4489 if ((ifp = ifunit(altq->ifname)) == NULL)
4490 altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
4491 else
4492 error = altq_add(ifp, altq);
4493
4494 if (error) {
4495 PF_RULES_WUNLOCK();
4496 free(altq, M_PFALTQ);
4497 goto fail;
4498 }
4499
4500 if (altq->qname[0] != 0)
4501 TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries);
4502 else
4503 TAILQ_INSERT_TAIL(V_pf_altq_ifs_inactive, altq, entries);
4504 /* version error check done on import above */
4505 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
4506 PF_RULES_WUNLOCK();
4507 break;
4508 }
4509
4510 case DIOCGETALTQSV0:
4511 case DIOCGETALTQSV1: {
4512 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
4513 struct pf_altq *altq;
4514
4515 PF_RULES_RLOCK();
4516 pa->nr = 0;
4517 TAILQ_FOREACH(altq, V_pf_altq_ifs_active, entries)
4518 pa->nr++;
4519 TAILQ_FOREACH(altq, V_pf_altqs_active, entries)
4520 pa->nr++;
4521 pa->ticket = V_ticket_altqs_active;
4522 PF_RULES_RUNLOCK();
4523 break;
4524 }
4525
4526 case DIOCGETALTQV0:
4527 case DIOCGETALTQV1: {
4528 struct pfioc_altq_v1 *pa = (struct pfioc_altq_v1 *)addr;
4529 struct pf_altq *altq;
4530
4531 PF_RULES_RLOCK();
4532 if (pa->ticket != V_ticket_altqs_active) {
4533 PF_RULES_RUNLOCK();
4534 error = EBUSY;
4535 goto fail;
4536 }
4537 altq = pf_altq_get_nth_active(pa->nr);
4538 if (altq == NULL) {
4539 PF_RULES_RUNLOCK();
4540 error = EBUSY;
4541 goto fail;
4542 }
4543 pf_export_kaltq(altq, pa, IOCPARM_LEN(cmd));
4544 PF_RULES_RUNLOCK();
4545 break;
4546 }
4547
4548 case DIOCCHANGEALTQV0:
4549 case DIOCCHANGEALTQV1:
4550 /* CHANGEALTQ not supported yet! */
4551 error = ENODEV;
4552 break;
4553
4554 case DIOCGETQSTATSV0:
4555 case DIOCGETQSTATSV1: {
4556 struct pfioc_qstats_v1 *pq = (struct pfioc_qstats_v1 *)addr;
4557 struct pf_altq *altq;
4558 int nbytes;
4559 u_int32_t version;
4560
4561 PF_RULES_RLOCK();
4562 if (pq->ticket != V_ticket_altqs_active) {
4563 PF_RULES_RUNLOCK();
4564 error = EBUSY;
4565 goto fail;
4566 }
4567 nbytes = pq->nbytes;
4568 altq = pf_altq_get_nth_active(pq->nr);
4569 if (altq == NULL) {
4570 PF_RULES_RUNLOCK();
4571 error = EBUSY;
4572 goto fail;
4573 }
4574
4575 if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) != 0) {
4576 PF_RULES_RUNLOCK();
4577 error = ENXIO;
4578 goto fail;
4579 }
4580 PF_RULES_RUNLOCK();
4581 if (cmd == DIOCGETQSTATSV0)
4582 version = 0; /* DIOCGETQSTATSV0 means stats struct v0 */
4583 else
4584 version = pq->version;
4585 error = altq_getqstats(altq, pq->buf, &nbytes, version);
4586 if (error == 0) {
4587 pq->scheduler = altq->scheduler;
4588 pq->nbytes = nbytes;
4589 }
4590 break;
4591 }
4592 #endif /* ALTQ */
4593
4594 case DIOCBEGINADDRS: {
4595 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
4596
4597 error = pf_ioctl_begin_addrs(&pp->ticket);
4598 break;
4599 }
4600
4601 case DIOCADDADDR: {
4602 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
4603 struct pf_nl_pooladdr npp = {};
4604
4605 npp.which = PF_RDR;
4606 memcpy(&npp, pp, sizeof(*pp));
4607 error = pf_ioctl_add_addr(&npp);
4608 break;
4609 }
4610
4611 case DIOCGETADDRS: {
4612 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
4613 struct pf_nl_pooladdr npp = {};
4614
4615 npp.which = PF_RDR;
4616 memcpy(&npp, pp, sizeof(*pp));
4617 error = pf_ioctl_get_addrs(&npp);
4618 memcpy(pp, &npp, sizeof(*pp));
4619
4620 break;
4621 }
4622
4623 case DIOCGETADDR: {
4624 struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
4625 struct pf_nl_pooladdr npp = {};
4626
4627 npp.which = PF_RDR;
4628 memcpy(&npp, pp, sizeof(*pp));
4629 error = pf_ioctl_get_addr(&npp);
4630 memcpy(pp, &npp, sizeof(*pp));
4631
4632 break;
4633 }
4634
4635 case DIOCCHANGEADDR: {
4636 struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
4637 struct pf_kpool *pool;
4638 struct pf_kpooladdr *oldpa = NULL, *newpa = NULL;
4639 struct pf_kruleset *ruleset;
4640 struct pfi_kkif *kif = NULL;
4641
4642 pca->anchor[sizeof(pca->anchor) - 1] = '\0';
4643
4644 if (pca->action < PF_CHANGE_ADD_HEAD ||
4645 pca->action > PF_CHANGE_REMOVE) {
4646 error = EINVAL;
4647 goto fail;
4648 }
4649 if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
4650 pca->addr.addr.type != PF_ADDR_DYNIFTL &&
4651 pca->addr.addr.type != PF_ADDR_TABLE) {
4652 error = EINVAL;
4653 goto fail;
4654 }
4655 if (pca->addr.addr.p.dyn != NULL) {
4656 error = EINVAL;
4657 goto fail;
4658 }
4659
4660 if (pca->action != PF_CHANGE_REMOVE) {
4661 #ifndef INET
4662 if (pca->af == AF_INET) {
4663 error = EAFNOSUPPORT;
4664 goto fail;
4665 }
4666 #endif /* INET */
4667 #ifndef INET6
4668 if (pca->af == AF_INET6) {
4669 error = EAFNOSUPPORT;
4670 goto fail;
4671 }
4672 #endif /* INET6 */
4673 newpa = malloc(sizeof(*newpa), M_PFRULE, M_WAITOK);
4674 bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr));
4675 if (newpa->ifname[0])
4676 kif = pf_kkif_create(M_WAITOK);
4677 newpa->kif = NULL;
4678 }
4679 #define ERROUT(x) ERROUT_IOCTL(DIOCCHANGEADDR_error, x)
4680 PF_RULES_WLOCK();
4681 ruleset = pf_find_kruleset(pca->anchor);
4682 if (ruleset == NULL)
4683 ERROUT(EBUSY);
4684
4685 pool = pf_get_kpool(pca->anchor, pca->ticket, pca->r_action,
4686 pca->r_num, pca->r_last, 1, 1, PF_RDR);
4687 if (pool == NULL)
4688 ERROUT(EBUSY);
4689
4690 if (pca->action != PF_CHANGE_REMOVE) {
4691 if (newpa->ifname[0]) {
4692 newpa->kif = pfi_kkif_attach(kif, newpa->ifname);
4693 pfi_kkif_ref(newpa->kif);
4694 kif = NULL;
4695 }
4696
4697 switch (newpa->addr.type) {
4698 case PF_ADDR_DYNIFTL:
4699 error = pfi_dynaddr_setup(&newpa->addr,
4700 pca->af);
4701 break;
4702 case PF_ADDR_TABLE:
4703 newpa->addr.p.tbl = pfr_attach_table(ruleset,
4704 newpa->addr.v.tblname);
4705 if (newpa->addr.p.tbl == NULL)
4706 error = ENOMEM;
4707 break;
4708 }
4709 if (error)
4710 goto DIOCCHANGEADDR_error;
4711 }
4712
4713 switch (pca->action) {
4714 case PF_CHANGE_ADD_HEAD:
4715 oldpa = TAILQ_FIRST(&pool->list);
4716 break;
4717 case PF_CHANGE_ADD_TAIL:
4718 oldpa = TAILQ_LAST(&pool->list, pf_kpalist);
4719 break;
4720 default:
4721 oldpa = TAILQ_FIRST(&pool->list);
4722 for (int i = 0; oldpa && i < pca->nr; i++)
4723 oldpa = TAILQ_NEXT(oldpa, entries);
4724
4725 if (oldpa == NULL)
4726 ERROUT(EINVAL);
4727 }
4728
4729 if (pca->action == PF_CHANGE_REMOVE) {
4730 TAILQ_REMOVE(&pool->list, oldpa, entries);
4731 switch (oldpa->addr.type) {
4732 case PF_ADDR_DYNIFTL:
4733 pfi_dynaddr_remove(oldpa->addr.p.dyn);
4734 break;
4735 case PF_ADDR_TABLE:
4736 pfr_detach_table(oldpa->addr.p.tbl);
4737 break;
4738 }
4739 if (oldpa->kif)
4740 pfi_kkif_unref(oldpa->kif);
4741 free(oldpa, M_PFRULE);
4742 } else {
4743 if (oldpa == NULL)
4744 TAILQ_INSERT_TAIL(&pool->list, newpa, entries);
4745 else if (pca->action == PF_CHANGE_ADD_HEAD ||
4746 pca->action == PF_CHANGE_ADD_BEFORE)
4747 TAILQ_INSERT_BEFORE(oldpa, newpa, entries);
4748 else
4749 TAILQ_INSERT_AFTER(&pool->list, oldpa,
4750 newpa, entries);
4751 }
4752
4753 pool->cur = TAILQ_FIRST(&pool->list);
4754 pf_addrcpy(&pool->counter, &pool->cur->addr.v.a.addr, pca->af);
4755 PF_RULES_WUNLOCK();
4756 break;
4757
4758 #undef ERROUT
4759 DIOCCHANGEADDR_error:
4760 if (newpa != NULL) {
4761 if (newpa->kif)
4762 pfi_kkif_unref(newpa->kif);
4763 free(newpa, M_PFRULE);
4764 }
4765 PF_RULES_WUNLOCK();
4766 pf_kkif_free(kif);
4767 break;
4768 }
4769
4770 case DIOCGETRULESETS: {
4771 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
4772
4773 pr->path[sizeof(pr->path) - 1] = '\0';
4774
4775 error = pf_ioctl_get_rulesets(pr);
4776 break;
4777 }
4778
4779 case DIOCGETRULESET: {
4780 struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
4781
4782 pr->path[sizeof(pr->path) - 1] = '\0';
4783
4784 error = pf_ioctl_get_ruleset(pr);
4785 break;
4786 }
4787
4788 case DIOCRCLRTABLES: {
4789 struct pfioc_table *io = (struct pfioc_table *)addr;
4790
4791 if (io->pfrio_esize != 0) {
4792 error = ENODEV;
4793 goto fail;
4794 }
4795 if (strnlen(io->pfrio_table.pfrt_anchor, MAXPATHLEN)
4796 == MAXPATHLEN) {
4797 error = EINVAL;
4798 goto fail;
4799 }
4800 if (strnlen(io->pfrio_table.pfrt_name, PF_TABLE_NAME_SIZE)
4801 == PF_TABLE_NAME_SIZE) {
4802 error = EINVAL;
4803 goto fail;
4804 }
4805
4806 PF_RULES_WLOCK();
4807 error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,
4808 io->pfrio_flags | PFR_FLAG_USERIOCTL);
4809 PF_RULES_WUNLOCK();
4810 break;
4811 }
4812
4813 case DIOCRADDTABLES: {
4814 struct pfioc_table *io = (struct pfioc_table *)addr;
4815 struct pfr_table *pfrts;
4816 size_t totlen;
4817
4818 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4819 error = ENODEV;
4820 goto fail;
4821 }
4822
4823 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4824 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4825 error = ENOMEM;
4826 goto fail;
4827 }
4828
4829 totlen = io->pfrio_size * sizeof(struct pfr_table);
4830 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4831 M_PF, M_WAITOK);
4832 error = copyin(io->pfrio_buffer, pfrts, totlen);
4833 if (error) {
4834 free(pfrts, M_PF);
4835 goto fail;
4836 }
4837 PF_RULES_WLOCK();
4838 error = pfr_add_tables(pfrts, io->pfrio_size,
4839 &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4840 PF_RULES_WUNLOCK();
4841 free(pfrts, M_PF);
4842 break;
4843 }
4844
4845 case DIOCRDELTABLES: {
4846 struct pfioc_table *io = (struct pfioc_table *)addr;
4847 struct pfr_table *pfrts;
4848 size_t totlen;
4849
4850 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4851 error = ENODEV;
4852 goto fail;
4853 }
4854
4855 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4856 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4857 error = ENOMEM;
4858 goto fail;
4859 }
4860
4861 totlen = io->pfrio_size * sizeof(struct pfr_table);
4862 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4863 M_PF, M_WAITOK);
4864 error = copyin(io->pfrio_buffer, pfrts, totlen);
4865 if (error) {
4866 free(pfrts, M_PF);
4867 goto fail;
4868 }
4869 PF_RULES_WLOCK();
4870 error = pfr_del_tables(pfrts, io->pfrio_size,
4871 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4872 PF_RULES_WUNLOCK();
4873 free(pfrts, M_PF);
4874 break;
4875 }
4876
4877 case DIOCRGETTABLES: {
4878 struct pfioc_table *io = (struct pfioc_table *)addr;
4879 struct pfr_table *pfrts;
4880 size_t totlen;
4881 int n;
4882
4883 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4884 error = ENODEV;
4885 goto fail;
4886 }
4887 PF_RULES_RLOCK();
4888 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4889 if (n < 0) {
4890 PF_RULES_RUNLOCK();
4891 error = EINVAL;
4892 goto fail;
4893 }
4894 io->pfrio_size = min(io->pfrio_size, n);
4895
4896 totlen = io->pfrio_size * sizeof(struct pfr_table);
4897
4898 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4899 M_PF, M_NOWAIT | M_ZERO);
4900 if (pfrts == NULL) {
4901 error = ENOMEM;
4902 PF_RULES_RUNLOCK();
4903 goto fail;
4904 }
4905 error = pfr_get_tables(&io->pfrio_table, pfrts,
4906 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4907 PF_RULES_RUNLOCK();
4908 if (error == 0)
4909 error = copyout(pfrts, io->pfrio_buffer, totlen);
4910 free(pfrts, M_PF);
4911 break;
4912 }
4913
4914 case DIOCRGETTSTATS: {
4915 struct pfioc_table *io = (struct pfioc_table *)addr;
4916 struct pfr_tstats *pfrtstats;
4917 size_t totlen;
4918 int n;
4919
4920 if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
4921 error = ENODEV;
4922 goto fail;
4923 }
4924 PF_TABLE_STATS_LOCK();
4925 PF_RULES_RLOCK();
4926 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
4927 if (n < 0) {
4928 PF_RULES_RUNLOCK();
4929 PF_TABLE_STATS_UNLOCK();
4930 error = EINVAL;
4931 goto fail;
4932 }
4933 io->pfrio_size = min(io->pfrio_size, n);
4934
4935 totlen = io->pfrio_size * sizeof(struct pfr_tstats);
4936 pfrtstats = mallocarray(io->pfrio_size,
4937 sizeof(struct pfr_tstats), M_PF, M_NOWAIT | M_ZERO);
4938 if (pfrtstats == NULL) {
4939 error = ENOMEM;
4940 PF_RULES_RUNLOCK();
4941 PF_TABLE_STATS_UNLOCK();
4942 goto fail;
4943 }
4944 error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
4945 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4946 PF_RULES_RUNLOCK();
4947 PF_TABLE_STATS_UNLOCK();
4948 if (error == 0)
4949 error = copyout(pfrtstats, io->pfrio_buffer, totlen);
4950 free(pfrtstats, M_PF);
4951 break;
4952 }
4953
4954 case DIOCRCLRTSTATS: {
4955 struct pfioc_table *io = (struct pfioc_table *)addr;
4956 struct pfr_table *pfrts;
4957 size_t totlen;
4958
4959 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4960 error = ENODEV;
4961 goto fail;
4962 }
4963
4964 if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
4965 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
4966 /* We used to count tables and use the minimum required
4967 * size, so we didn't fail on overly large requests.
4968 * Keep doing so. */
4969 io->pfrio_size = pf_ioctl_maxcount;
4970 goto fail;
4971 }
4972
4973 totlen = io->pfrio_size * sizeof(struct pfr_table);
4974 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
4975 M_PF, M_WAITOK);
4976 error = copyin(io->pfrio_buffer, pfrts, totlen);
4977 if (error) {
4978 free(pfrts, M_PF);
4979 goto fail;
4980 }
4981
4982 PF_TABLE_STATS_LOCK();
4983 PF_RULES_RLOCK();
4984 error = pfr_clr_tstats(pfrts, io->pfrio_size,
4985 &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
4986 PF_RULES_RUNLOCK();
4987 PF_TABLE_STATS_UNLOCK();
4988 free(pfrts, M_PF);
4989 break;
4990 }
4991
4992 case DIOCRSETTFLAGS: {
4993 struct pfioc_table *io = (struct pfioc_table *)addr;
4994 struct pfr_table *pfrts;
4995 size_t totlen;
4996 int n;
4997
4998 if (io->pfrio_esize != sizeof(struct pfr_table)) {
4999 error = ENODEV;
5000 goto fail;
5001 }
5002
5003 PF_RULES_RLOCK();
5004 n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
5005 if (n < 0) {
5006 PF_RULES_RUNLOCK();
5007 error = EINVAL;
5008 goto fail;
5009 }
5010
5011 io->pfrio_size = min(io->pfrio_size, n);
5012 PF_RULES_RUNLOCK();
5013
5014 totlen = io->pfrio_size * sizeof(struct pfr_table);
5015 pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
5016 M_PF, M_WAITOK);
5017 error = copyin(io->pfrio_buffer, pfrts, totlen);
5018 if (error) {
5019 free(pfrts, M_PF);
5020 goto fail;
5021 }
5022 PF_RULES_WLOCK();
5023 error = pfr_set_tflags(pfrts, io->pfrio_size,
5024 io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
5025 &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
5026 PF_RULES_WUNLOCK();
5027 free(pfrts, M_PF);
5028 break;
5029 }
5030
5031 case DIOCRCLRADDRS: {
5032 struct pfioc_table *io = (struct pfioc_table *)addr;
5033
5034 if (io->pfrio_esize != 0) {
5035 error = ENODEV;
5036 goto fail;
5037 }
5038 PF_RULES_WLOCK();
5039 error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
5040 io->pfrio_flags | PFR_FLAG_USERIOCTL);
5041 PF_RULES_WUNLOCK();
5042 break;
5043 }
5044
5045 case DIOCRADDADDRS: {
5046 struct pfioc_table *io = (struct pfioc_table *)addr;
5047 struct pfr_addr *pfras;
5048 size_t totlen;
5049
5050 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
5051 error = ENODEV;
5052 goto fail;
5053 }
5054 if (io->pfrio_size < 0 ||
5055 io->pfrio_size > pf_ioctl_maxcount ||
5056 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
5057 error = EINVAL;
5058 goto fail;
5059 }
5060 totlen = io->pfrio_size * sizeof(struct pfr_addr);
5061 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
5062 M_PF, M_WAITOK);
5063 error = copyin(io->pfrio_buffer, pfras, totlen);
5064 if (error) {
5065 free(pfras, M_PF);
5066 goto fail;
5067 }
5068 PF_RULES_WLOCK();
5069 io->pfrio_nadd = 0;
5070 error = pfr_add_addrs(&io->pfrio_table, pfras,
5071 io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
5072 PFR_FLAG_USERIOCTL);
5073 PF_RULES_WUNLOCK();
5074 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
5075 error = copyout(pfras, io->pfrio_buffer, totlen);
5076 free(pfras, M_PF);
5077 break;
5078 }
5079
5080 case DIOCRDELADDRS: {
5081 struct pfioc_table *io = (struct pfioc_table *)addr;
5082 struct pfr_addr *pfras;
5083 size_t totlen;
5084
5085 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
5086 error = ENODEV;
5087 goto fail;
5088 }
5089 if (io->pfrio_size < 0 ||
5090 io->pfrio_size > pf_ioctl_maxcount ||
5091 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
5092 error = EINVAL;
5093 goto fail;
5094 }
5095 totlen = io->pfrio_size * sizeof(struct pfr_addr);
5096 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
5097 M_PF, M_WAITOK);
5098 error = copyin(io->pfrio_buffer, pfras, totlen);
5099 if (error) {
5100 free(pfras, M_PF);
5101 goto fail;
5102 }
5103 PF_RULES_WLOCK();
5104 error = pfr_del_addrs(&io->pfrio_table, pfras,
5105 io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
5106 PFR_FLAG_USERIOCTL);
5107 PF_RULES_WUNLOCK();
5108 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
5109 error = copyout(pfras, io->pfrio_buffer, totlen);
5110 free(pfras, M_PF);
5111 break;
5112 }
5113
5114 case DIOCRSETADDRS: {
5115 struct pfioc_table *io = (struct pfioc_table *)addr;
5116 struct pfr_addr *pfras;
5117 size_t totlen, count;
5118
5119 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
5120 error = ENODEV;
5121 goto fail;
5122 }
5123 if (io->pfrio_size < 0 || io->pfrio_size2 < 0) {
5124 error = EINVAL;
5125 goto fail;
5126 }
5127 count = max(io->pfrio_size, io->pfrio_size2);
5128 if (count > pf_ioctl_maxcount ||
5129 WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) {
5130 error = EINVAL;
5131 goto fail;
5132 }
5133 totlen = count * sizeof(struct pfr_addr);
5134 pfras = mallocarray(count, sizeof(struct pfr_addr), M_PF,
5135 M_WAITOK);
5136 error = copyin(io->pfrio_buffer, pfras, totlen);
5137 if (error) {
5138 free(pfras, M_PF);
5139 goto fail;
5140 }
5141 PF_RULES_WLOCK();
5142 error = pfr_set_addrs(&io->pfrio_table, pfras,
5143 io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
5144 &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
5145 PFR_FLAG_START | PFR_FLAG_DONE | PFR_FLAG_USERIOCTL, 0);
5146 PF_RULES_WUNLOCK();
5147 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
5148 error = copyout(pfras, io->pfrio_buffer, totlen);
5149 free(pfras, M_PF);
5150 break;
5151 }
5152
5153 case DIOCRGETADDRS: {
5154 struct pfioc_table *io = (struct pfioc_table *)addr;
5155 struct pfr_addr *pfras;
5156 size_t totlen;
5157
5158 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
5159 error = ENODEV;
5160 goto fail;
5161 }
5162 if (io->pfrio_size < 0 ||
5163 io->pfrio_size > pf_ioctl_maxcount ||
5164 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
5165 error = EINVAL;
5166 goto fail;
5167 }
5168 totlen = io->pfrio_size * sizeof(struct pfr_addr);
5169 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
5170 M_PF, M_WAITOK | M_ZERO);
5171 PF_RULES_RLOCK();
5172 error = pfr_get_addrs(&io->pfrio_table, pfras,
5173 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
5174 PF_RULES_RUNLOCK();
5175 if (error == 0)
5176 error = copyout(pfras, io->pfrio_buffer, totlen);
5177 free(pfras, M_PF);
5178 break;
5179 }
5180
5181 case DIOCRGETASTATS: {
5182 struct pfioc_table *io = (struct pfioc_table *)addr;
5183 struct pfr_astats *pfrastats;
5184 size_t totlen;
5185
5186 if (io->pfrio_esize != sizeof(struct pfr_astats)) {
5187 error = ENODEV;
5188 goto fail;
5189 }
5190 if (io->pfrio_size < 0 ||
5191 io->pfrio_size > pf_ioctl_maxcount ||
5192 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) {
5193 error = EINVAL;
5194 goto fail;
5195 }
5196 totlen = io->pfrio_size * sizeof(struct pfr_astats);
5197 pfrastats = mallocarray(io->pfrio_size,
5198 sizeof(struct pfr_astats), M_PF, M_WAITOK | M_ZERO);
5199 PF_RULES_RLOCK();
5200 error = pfr_get_astats(&io->pfrio_table, pfrastats,
5201 &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
5202 PF_RULES_RUNLOCK();
5203 if (error == 0)
5204 error = copyout(pfrastats, io->pfrio_buffer, totlen);
5205 free(pfrastats, M_PF);
5206 break;
5207 }
5208
5209 case DIOCRCLRASTATS: {
5210 struct pfioc_table *io = (struct pfioc_table *)addr;
5211 struct pfr_addr *pfras;
5212 size_t totlen;
5213
5214 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
5215 error = ENODEV;
5216 goto fail;
5217 }
5218 if (io->pfrio_size < 0 ||
5219 io->pfrio_size > pf_ioctl_maxcount ||
5220 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
5221 error = EINVAL;
5222 goto fail;
5223 }
5224 totlen = io->pfrio_size * sizeof(struct pfr_addr);
5225 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
5226 M_PF, M_WAITOK);
5227 error = copyin(io->pfrio_buffer, pfras, totlen);
5228 if (error) {
5229 free(pfras, M_PF);
5230 goto fail;
5231 }
5232 PF_RULES_WLOCK();
5233 error = pfr_clr_astats(&io->pfrio_table, pfras,
5234 io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
5235 PFR_FLAG_USERIOCTL);
5236 PF_RULES_WUNLOCK();
5237 if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
5238 error = copyout(pfras, io->pfrio_buffer, totlen);
5239 free(pfras, M_PF);
5240 break;
5241 }
5242
5243 case DIOCRTSTADDRS: {
5244 struct pfioc_table *io = (struct pfioc_table *)addr;
5245 struct pfr_addr *pfras;
5246 size_t totlen;
5247
5248 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
5249 error = ENODEV;
5250 goto fail;
5251 }
5252 if (io->pfrio_size < 0 ||
5253 io->pfrio_size > pf_ioctl_maxcount ||
5254 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
5255 error = EINVAL;
5256 goto fail;
5257 }
5258 totlen = io->pfrio_size * sizeof(struct pfr_addr);
5259 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
5260 M_PF, M_WAITOK);
5261 error = copyin(io->pfrio_buffer, pfras, totlen);
5262 if (error) {
5263 free(pfras, M_PF);
5264 goto fail;
5265 }
5266 PF_RULES_RLOCK();
5267 error = pfr_tst_addrs(&io->pfrio_table, pfras,
5268 io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
5269 PFR_FLAG_USERIOCTL);
5270 PF_RULES_RUNLOCK();
5271 if (error == 0)
5272 error = copyout(pfras, io->pfrio_buffer, totlen);
5273 free(pfras, M_PF);
5274 break;
5275 }
5276
5277 case DIOCRINADEFINE: {
5278 struct pfioc_table *io = (struct pfioc_table *)addr;
5279 struct pfr_addr *pfras;
5280 size_t totlen;
5281
5282 if (io->pfrio_esize != sizeof(struct pfr_addr)) {
5283 error = ENODEV;
5284 goto fail;
5285 }
5286 if (io->pfrio_size < 0 ||
5287 io->pfrio_size > pf_ioctl_maxcount ||
5288 WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
5289 error = EINVAL;
5290 goto fail;
5291 }
5292 totlen = io->pfrio_size * sizeof(struct pfr_addr);
5293 pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
5294 M_PF, M_WAITOK);
5295 error = copyin(io->pfrio_buffer, pfras, totlen);
5296 if (error) {
5297 free(pfras, M_PF);
5298 goto fail;
5299 }
5300 PF_RULES_WLOCK();
5301 error = pfr_ina_define(&io->pfrio_table, pfras,
5302 io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
5303 io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
5304 PF_RULES_WUNLOCK();
5305 free(pfras, M_PF);
5306 break;
5307 }
5308
5309 case DIOCOSFPADD: {
5310 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
5311 PF_RULES_WLOCK();
5312 error = pf_osfp_add(io);
5313 PF_RULES_WUNLOCK();
5314 break;
5315 }
5316
5317 case DIOCOSFPGET: {
5318 struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
5319 PF_RULES_RLOCK();
5320 error = pf_osfp_get(io);
5321 PF_RULES_RUNLOCK();
5322 break;
5323 }
5324
5325 case DIOCXBEGIN: {
5326 struct pfioc_trans *io = (struct pfioc_trans *)addr;
5327 struct pfioc_trans_e *ioes, *ioe;
5328 size_t totlen;
5329 int i;
5330
5331 if (io->esize != sizeof(*ioe)) {
5332 error = ENODEV;
5333 goto fail;
5334 }
5335 if (io->size < 0 ||
5336 io->size > pf_ioctl_maxcount ||
5337 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
5338 error = EINVAL;
5339 goto fail;
5340 }
5341 totlen = sizeof(struct pfioc_trans_e) * io->size;
5342 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
5343 M_PF, M_WAITOK);
5344 error = copyin(io->array, ioes, totlen);
5345 if (error) {
5346 free(ioes, M_PF);
5347 goto fail;
5348 }
5349 PF_RULES_WLOCK();
5350 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5351 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
5352 switch (ioe->rs_num) {
5353 case PF_RULESET_ETH:
5354 if ((error = pf_begin_eth(&ioe->ticket, ioe->anchor))) {
5355 PF_RULES_WUNLOCK();
5356 free(ioes, M_PF);
5357 goto fail;
5358 }
5359 break;
5360 #ifdef ALTQ
5361 case PF_RULESET_ALTQ:
5362 if (ioe->anchor[0]) {
5363 PF_RULES_WUNLOCK();
5364 free(ioes, M_PF);
5365 error = EINVAL;
5366 goto fail;
5367 }
5368 if ((error = pf_begin_altq(&ioe->ticket))) {
5369 PF_RULES_WUNLOCK();
5370 free(ioes, M_PF);
5371 goto fail;
5372 }
5373 break;
5374 #endif /* ALTQ */
5375 case PF_RULESET_TABLE:
5376 {
5377 struct pfr_table table;
5378
5379 bzero(&table, sizeof(table));
5380 strlcpy(table.pfrt_anchor, ioe->anchor,
5381 sizeof(table.pfrt_anchor));
5382 if ((error = pfr_ina_begin(&table,
5383 &ioe->ticket, NULL, 0))) {
5384 PF_RULES_WUNLOCK();
5385 free(ioes, M_PF);
5386 goto fail;
5387 }
5388 break;
5389 }
5390 default:
5391 if ((error = pf_begin_rules(&ioe->ticket,
5392 ioe->rs_num, ioe->anchor))) {
5393 PF_RULES_WUNLOCK();
5394 free(ioes, M_PF);
5395 goto fail;
5396 }
5397 break;
5398 }
5399 }
5400 PF_RULES_WUNLOCK();
5401 error = copyout(ioes, io->array, totlen);
5402 free(ioes, M_PF);
5403 break;
5404 }
5405
5406 case DIOCXROLLBACK: {
5407 struct pfioc_trans *io = (struct pfioc_trans *)addr;
5408 struct pfioc_trans_e *ioe, *ioes;
5409 size_t totlen;
5410 int i;
5411
5412 if (io->esize != sizeof(*ioe)) {
5413 error = ENODEV;
5414 goto fail;
5415 }
5416 if (io->size < 0 ||
5417 io->size > pf_ioctl_maxcount ||
5418 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
5419 error = EINVAL;
5420 goto fail;
5421 }
5422 totlen = sizeof(struct pfioc_trans_e) * io->size;
5423 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
5424 M_PF, M_WAITOK);
5425 error = copyin(io->array, ioes, totlen);
5426 if (error) {
5427 free(ioes, M_PF);
5428 goto fail;
5429 }
5430 PF_RULES_WLOCK();
5431 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5432 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
5433 switch (ioe->rs_num) {
5434 case PF_RULESET_ETH:
5435 if ((error = pf_rollback_eth(ioe->ticket,
5436 ioe->anchor))) {
5437 PF_RULES_WUNLOCK();
5438 free(ioes, M_PF);
5439 goto fail; /* really bad */
5440 }
5441 break;
5442 #ifdef ALTQ
5443 case PF_RULESET_ALTQ:
5444 if (ioe->anchor[0]) {
5445 PF_RULES_WUNLOCK();
5446 free(ioes, M_PF);
5447 error = EINVAL;
5448 goto fail;
5449 }
5450 if ((error = pf_rollback_altq(ioe->ticket))) {
5451 PF_RULES_WUNLOCK();
5452 free(ioes, M_PF);
5453 goto fail; /* really bad */
5454 }
5455 break;
5456 #endif /* ALTQ */
5457 case PF_RULESET_TABLE:
5458 {
5459 struct pfr_table table;
5460
5461 bzero(&table, sizeof(table));
5462 strlcpy(table.pfrt_anchor, ioe->anchor,
5463 sizeof(table.pfrt_anchor));
5464 if ((error = pfr_ina_rollback(&table,
5465 ioe->ticket, NULL, 0))) {
5466 PF_RULES_WUNLOCK();
5467 free(ioes, M_PF);
5468 goto fail; /* really bad */
5469 }
5470 break;
5471 }
5472 default:
5473 if ((error = pf_rollback_rules(ioe->ticket,
5474 ioe->rs_num, ioe->anchor))) {
5475 PF_RULES_WUNLOCK();
5476 free(ioes, M_PF);
5477 goto fail; /* really bad */
5478 }
5479 break;
5480 }
5481 }
5482 PF_RULES_WUNLOCK();
5483 free(ioes, M_PF);
5484 break;
5485 }
5486
5487 case DIOCXCOMMIT: {
5488 struct pfioc_trans *io = (struct pfioc_trans *)addr;
5489 struct pfioc_trans_e *ioe, *ioes;
5490 struct pf_kruleset *rs;
5491 struct pf_keth_ruleset *ers;
5492 size_t totlen;
5493 int i;
5494
5495 if (io->esize != sizeof(*ioe)) {
5496 error = ENODEV;
5497 goto fail;
5498 }
5499
5500 if (io->size < 0 ||
5501 io->size > pf_ioctl_maxcount ||
5502 WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
5503 error = EINVAL;
5504 goto fail;
5505 }
5506
5507 totlen = sizeof(struct pfioc_trans_e) * io->size;
5508 ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
5509 M_PF, M_WAITOK);
5510 error = copyin(io->array, ioes, totlen);
5511 if (error) {
5512 free(ioes, M_PF);
5513 goto fail;
5514 }
5515 PF_RULES_WLOCK();
5516 /* First makes sure everything will succeed. */
5517 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5518 ioe->anchor[sizeof(ioe->anchor) - 1] = '\0';
5519 switch (ioe->rs_num) {
5520 case PF_RULESET_ETH:
5521 ers = pf_find_keth_ruleset(ioe->anchor);
5522 if (ers == NULL || ioe->ticket == 0 ||
5523 ioe->ticket != ers->inactive.ticket) {
5524 PF_RULES_WUNLOCK();
5525 free(ioes, M_PF);
5526 error = EINVAL;
5527 goto fail;
5528 }
5529 break;
5530 #ifdef ALTQ
5531 case PF_RULESET_ALTQ:
5532 if (ioe->anchor[0]) {
5533 PF_RULES_WUNLOCK();
5534 free(ioes, M_PF);
5535 error = EINVAL;
5536 goto fail;
5537 }
5538 if (!V_altqs_inactive_open || ioe->ticket !=
5539 V_ticket_altqs_inactive) {
5540 PF_RULES_WUNLOCK();
5541 free(ioes, M_PF);
5542 error = EBUSY;
5543 goto fail;
5544 }
5545 break;
5546 #endif /* ALTQ */
5547 case PF_RULESET_TABLE:
5548 rs = pf_find_kruleset(ioe->anchor);
5549 if (rs == NULL || !rs->topen || ioe->ticket !=
5550 rs->tticket) {
5551 PF_RULES_WUNLOCK();
5552 free(ioes, M_PF);
5553 error = EBUSY;
5554 goto fail;
5555 }
5556 break;
5557 default:
5558 if (ioe->rs_num < 0 || ioe->rs_num >=
5559 PF_RULESET_MAX) {
5560 PF_RULES_WUNLOCK();
5561 free(ioes, M_PF);
5562 error = EINVAL;
5563 goto fail;
5564 }
5565 rs = pf_find_kruleset(ioe->anchor);
5566 if (rs == NULL ||
5567 !rs->rules[ioe->rs_num].inactive.open ||
5568 rs->rules[ioe->rs_num].inactive.ticket !=
5569 ioe->ticket) {
5570 PF_RULES_WUNLOCK();
5571 free(ioes, M_PF);
5572 error = EBUSY;
5573 goto fail;
5574 }
5575 break;
5576 }
5577 }
5578 /* Now do the commit - no errors should happen here. */
5579 for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
5580 switch (ioe->rs_num) {
5581 case PF_RULESET_ETH:
5582 if ((error = pf_commit_eth(ioe->ticket, ioe->anchor))) {
5583 PF_RULES_WUNLOCK();
5584 free(ioes, M_PF);
5585 goto fail; /* really bad */
5586 }
5587 break;
5588 #ifdef ALTQ
5589 case PF_RULESET_ALTQ:
5590 if ((error = pf_commit_altq(ioe->ticket))) {
5591 PF_RULES_WUNLOCK();
5592 free(ioes, M_PF);
5593 goto fail; /* really bad */
5594 }
5595 break;
5596 #endif /* ALTQ */
5597 case PF_RULESET_TABLE:
5598 {
5599 struct pfr_table table;
5600
5601 bzero(&table, sizeof(table));
5602 (void)strlcpy(table.pfrt_anchor, ioe->anchor,
5603 sizeof(table.pfrt_anchor));
5604 if ((error = pfr_ina_commit(&table,
5605 ioe->ticket, NULL, NULL, 0))) {
5606 PF_RULES_WUNLOCK();
5607 free(ioes, M_PF);
5608 goto fail; /* really bad */
5609 }
5610 break;
5611 }
5612 default:
5613 if ((error = pf_commit_rules(ioe->ticket,
5614 ioe->rs_num, ioe->anchor))) {
5615 PF_RULES_WUNLOCK();
5616 free(ioes, M_PF);
5617 goto fail; /* really bad */
5618 }
5619 break;
5620 }
5621 }
5622 PF_RULES_WUNLOCK();
5623
5624 /* Only hook into EtherNet taffic if we've got rules for it. */
5625 if (! TAILQ_EMPTY(V_pf_keth->active.rules))
5626 hook_pf_eth();
5627 else
5628 dehook_pf_eth();
5629
5630 free(ioes, M_PF);
5631 break;
5632 }
5633
5634 case DIOCGETSRCNODES: {
5635 struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr;
5636 struct pf_srchash *sh;
5637 struct pf_ksrc_node *n;
5638 struct pf_src_node *p, *pstore;
5639 uint32_t i, nr = 0;
5640
5641 for (i = 0, sh = V_pf_srchash; i <= V_pf_srchashmask;
5642 i++, sh++) {
5643 PF_HASHROW_LOCK(sh);
5644 LIST_FOREACH(n, &sh->nodes, entry)
5645 nr++;
5646 PF_HASHROW_UNLOCK(sh);
5647 }
5648
5649 psn->psn_len = min(psn->psn_len,
5650 sizeof(struct pf_src_node) * nr);
5651
5652 if (psn->psn_len == 0) {
5653 psn->psn_len = sizeof(struct pf_src_node) * nr;
5654 goto fail;
5655 }
5656
5657 nr = 0;
5658
5659 p = pstore = malloc(psn->psn_len, M_PF, M_WAITOK | M_ZERO);
5660 for (i = 0, sh = V_pf_srchash; i <= V_pf_srchashmask;
5661 i++, sh++) {
5662 PF_HASHROW_LOCK(sh);
5663 LIST_FOREACH(n, &sh->nodes, entry) {
5664
5665 if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
5666 break;
5667
5668 pf_src_node_copy(n, p);
5669
5670 p++;
5671 nr++;
5672 }
5673 PF_HASHROW_UNLOCK(sh);
5674 }
5675 error = copyout(pstore, psn->psn_src_nodes,
5676 sizeof(struct pf_src_node) * nr);
5677 if (error) {
5678 free(pstore, M_PF);
5679 goto fail;
5680 }
5681 psn->psn_len = sizeof(struct pf_src_node) * nr;
5682 free(pstore, M_PF);
5683 break;
5684 }
5685
5686 case DIOCCLRSRCNODES: {
5687 pf_kill_srcnodes(NULL);
5688 break;
5689 }
5690
5691 case DIOCKILLSRCNODES:
5692 pf_kill_srcnodes((struct pfioc_src_node_kill *)addr);
5693 break;
5694
5695 #ifdef COMPAT_FREEBSD13
5696 case DIOCKEEPCOUNTERS_FREEBSD13:
5697 #endif
5698 case DIOCKEEPCOUNTERS:
5699 error = pf_keepcounters((struct pfioc_nv *)addr);
5700 break;
5701
5702 case DIOCGETSYNCOOKIES:
5703 error = pf_get_syncookies((struct pfioc_nv *)addr);
5704 break;
5705
5706 case DIOCSETSYNCOOKIES:
5707 error = pf_set_syncookies((struct pfioc_nv *)addr);
5708 break;
5709
5710 case DIOCSETHOSTID: {
5711 u_int32_t *hostid = (u_int32_t *)addr;
5712
5713 PF_RULES_WLOCK();
5714 if (*hostid == 0)
5715 V_pf_status.hostid = arc4random();
5716 else
5717 V_pf_status.hostid = *hostid;
5718 PF_RULES_WUNLOCK();
5719 break;
5720 }
5721
5722 case DIOCOSFPFLUSH:
5723 PF_RULES_WLOCK();
5724 pf_osfp_flush();
5725 PF_RULES_WUNLOCK();
5726 break;
5727
5728 case DIOCIGETIFACES: {
5729 struct pfioc_iface *io = (struct pfioc_iface *)addr;
5730 struct pfi_kif *ifstore;
5731 size_t bufsiz;
5732
5733 if (io->pfiio_esize != sizeof(struct pfi_kif)) {
5734 error = ENODEV;
5735 goto fail;
5736 }
5737
5738 if (io->pfiio_size < 0 ||
5739 io->pfiio_size > pf_ioctl_maxcount ||
5740 WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) {
5741 error = EINVAL;
5742 goto fail;
5743 }
5744
5745 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5746
5747 bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
5748 ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
5749 M_PF, M_WAITOK | M_ZERO);
5750
5751 PF_RULES_RLOCK();
5752 pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
5753 PF_RULES_RUNLOCK();
5754 error = copyout(ifstore, io->pfiio_buffer, bufsiz);
5755 free(ifstore, M_PF);
5756 break;
5757 }
5758
5759 case DIOCSETIFFLAG: {
5760 struct pfioc_iface *io = (struct pfioc_iface *)addr;
5761
5762 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5763
5764 PF_RULES_WLOCK();
5765 error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
5766 PF_RULES_WUNLOCK();
5767 break;
5768 }
5769
5770 case DIOCCLRIFFLAG: {
5771 struct pfioc_iface *io = (struct pfioc_iface *)addr;
5772
5773 io->pfiio_name[sizeof(io->pfiio_name) - 1] = '\0';
5774
5775 PF_RULES_WLOCK();
5776 error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
5777 PF_RULES_WUNLOCK();
5778 break;
5779 }
5780
5781 case DIOCSETREASS: {
5782 u_int32_t *reass = (u_int32_t *)addr;
5783
5784 V_pf_status.reass = *reass & (PF_REASS_ENABLED|PF_REASS_NODF);
5785 /* Removal of DF flag without reassembly enabled is not a
5786 * valid combination. Disable reassembly in such case. */
5787 if (!(V_pf_status.reass & PF_REASS_ENABLED))
5788 V_pf_status.reass = 0;
5789 break;
5790 }
5791
5792 default:
5793 error = ENODEV;
5794 break;
5795 }
5796 fail:
5797 CURVNET_RESTORE();
5798
5799 #undef ERROUT_IOCTL
5800
5801 return (error);
5802 }
5803
5804 void
pfsync_state_export(union pfsync_state_union * sp,struct pf_kstate * st,int msg_version)5805 pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_version)
5806 {
5807 const char *tagname;
5808 bzero(sp, sizeof(union pfsync_state_union));
5809
5810 /* copy from state key */
5811 sp->pfs_1301.key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
5812 sp->pfs_1301.key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
5813 sp->pfs_1301.key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
5814 sp->pfs_1301.key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
5815 sp->pfs_1301.key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
5816 sp->pfs_1301.key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
5817 sp->pfs_1301.key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
5818 sp->pfs_1301.key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
5819
5820 /* copy from state */
5821 strlcpy(sp->pfs_1301.ifname, st->kif->pfik_name, sizeof(sp->pfs_1301.ifname));
5822 bcopy(&st->act.rt_addr, &sp->pfs_1301.rt_addr, sizeof(sp->pfs_1301.rt_addr));
5823 sp->pfs_1301.creation = htonl(time_uptime - (st->creation / 1000));
5824 sp->pfs_1301.expire = pf_state_expires(st);
5825 if (sp->pfs_1301.expire <= time_uptime)
5826 sp->pfs_1301.expire = htonl(0);
5827 else
5828 sp->pfs_1301.expire = htonl(sp->pfs_1301.expire - time_uptime);
5829
5830 switch (msg_version) {
5831 case PFSYNC_MSG_VERSION_1301:
5832 sp->pfs_1301.state_flags = st->state_flags;
5833 sp->pfs_1301.direction = st->direction;
5834 sp->pfs_1301.log = st->act.log;
5835 sp->pfs_1301.timeout = st->timeout;
5836 sp->pfs_1301.proto = st->key[PF_SK_WIRE]->proto;
5837 sp->pfs_1301.af = st->key[PF_SK_WIRE]->af;
5838 /*
5839 * XXX Why do we bother pfsyncing source node information if source
5840 * nodes are not synced? Showing users that there is source tracking
5841 * when there is none seems useless.
5842 */
5843 if (st->sns[PF_SN_LIMIT] != NULL)
5844 sp->pfs_1301.sync_flags |= PFSYNC_FLAG_SRCNODE;
5845 if (st->sns[PF_SN_NAT] != NULL || st->sns[PF_SN_ROUTE])
5846 sp->pfs_1301.sync_flags |= PFSYNC_FLAG_NATSRCNODE;
5847 break;
5848 case PFSYNC_MSG_VERSION_1400:
5849 sp->pfs_1400.state_flags = htons(st->state_flags);
5850 sp->pfs_1400.direction = st->direction;
5851 sp->pfs_1400.log = st->act.log;
5852 sp->pfs_1400.timeout = st->timeout;
5853 sp->pfs_1400.proto = st->key[PF_SK_WIRE]->proto;
5854 sp->pfs_1400.af = st->key[PF_SK_WIRE]->af;
5855 sp->pfs_1400.qid = htons(st->act.qid);
5856 sp->pfs_1400.pqid = htons(st->act.pqid);
5857 sp->pfs_1400.dnpipe = htons(st->act.dnpipe);
5858 sp->pfs_1400.dnrpipe = htons(st->act.dnrpipe);
5859 sp->pfs_1400.rtableid = htonl(st->act.rtableid);
5860 sp->pfs_1400.min_ttl = st->act.min_ttl;
5861 sp->pfs_1400.set_tos = st->act.set_tos;
5862 sp->pfs_1400.max_mss = htons(st->act.max_mss);
5863 sp->pfs_1400.set_prio[0] = st->act.set_prio[0];
5864 sp->pfs_1400.set_prio[1] = st->act.set_prio[1];
5865 sp->pfs_1400.rt = st->act.rt;
5866 if (st->act.rt_kif)
5867 strlcpy(sp->pfs_1400.rt_ifname,
5868 st->act.rt_kif->pfik_name,
5869 sizeof(sp->pfs_1400.rt_ifname));
5870 /*
5871 * XXX Why do we bother pfsyncing source node information if source
5872 * nodes are not synced? Showing users that there is source tracking
5873 * when there is none seems useless.
5874 */
5875 if (st->sns[PF_SN_LIMIT] != NULL)
5876 sp->pfs_1400.sync_flags |= PFSYNC_FLAG_SRCNODE;
5877 if (st->sns[PF_SN_NAT] != NULL || st->sns[PF_SN_ROUTE])
5878 sp->pfs_1400.sync_flags |= PFSYNC_FLAG_NATSRCNODE;
5879 break;
5880 case PFSYNC_MSG_VERSION_1500:
5881 sp->pfs_1500.state_flags = htons(st->state_flags);
5882 sp->pfs_1500.direction = st->direction;
5883 sp->pfs_1500.log = st->act.log;
5884 sp->pfs_1500.timeout = st->timeout;
5885 sp->pfs_1500.wire_proto = st->key[PF_SK_WIRE]->proto;
5886 sp->pfs_1500.wire_af = st->key[PF_SK_WIRE]->af;
5887 sp->pfs_1500.stack_proto = st->key[PF_SK_STACK]->proto;
5888 sp->pfs_1500.stack_af = st->key[PF_SK_STACK]->af;
5889 sp->pfs_1500.qid = htons(st->act.qid);
5890 sp->pfs_1500.pqid = htons(st->act.pqid);
5891 sp->pfs_1500.dnpipe = htons(st->act.dnpipe);
5892 sp->pfs_1500.dnrpipe = htons(st->act.dnrpipe);
5893 sp->pfs_1500.rtableid = htonl(st->act.rtableid);
5894 sp->pfs_1500.min_ttl = st->act.min_ttl;
5895 sp->pfs_1500.set_tos = st->act.set_tos;
5896 sp->pfs_1500.max_mss = htons(st->act.max_mss);
5897 sp->pfs_1500.set_prio[0] = st->act.set_prio[0];
5898 sp->pfs_1500.set_prio[1] = st->act.set_prio[1];
5899 sp->pfs_1500.rt = st->act.rt;
5900 sp->pfs_1500.rt_af = st->act.rt_af;
5901 if (st->act.rt_kif)
5902 strlcpy(sp->pfs_1500.rt_ifname,
5903 st->act.rt_kif->pfik_name,
5904 sizeof(sp->pfs_1500.rt_ifname));
5905 strlcpy(sp->pfs_1500.orig_ifname,
5906 st->orig_kif->pfik_name,
5907 sizeof(sp->pfs_1500.orig_ifname));
5908 if ((tagname = pf_tag2tagname(st->tag)) != NULL)
5909 strlcpy(sp->pfs_1500.tagname, tagname,
5910 sizeof(sp->pfs_1500.tagname));
5911 break;
5912 default:
5913 panic("%s: Unsupported pfsync_msg_version %d",
5914 __func__, msg_version);
5915 }
5916
5917 sp->pfs_1301.id = st->id;
5918 sp->pfs_1301.creatorid = st->creatorid;
5919 pf_state_peer_hton(&st->src, &sp->pfs_1301.src);
5920 pf_state_peer_hton(&st->dst, &sp->pfs_1301.dst);
5921
5922 if (st->rule == NULL)
5923 sp->pfs_1301.rule = htonl(-1);
5924 else
5925 sp->pfs_1301.rule = htonl(st->rule->nr);
5926 if (st->anchor == NULL)
5927 sp->pfs_1301.anchor = htonl(-1);
5928 else
5929 sp->pfs_1301.anchor = htonl(st->anchor->nr);
5930 if (st->nat_rule == NULL)
5931 sp->pfs_1301.nat_rule = htonl(-1);
5932 else
5933 sp->pfs_1301.nat_rule = htonl(st->nat_rule->nr);
5934
5935 pf_state_counter_hton(st->packets[0], sp->pfs_1301.packets[0]);
5936 pf_state_counter_hton(st->packets[1], sp->pfs_1301.packets[1]);
5937 pf_state_counter_hton(st->bytes[0], sp->pfs_1301.bytes[0]);
5938 pf_state_counter_hton(st->bytes[1], sp->pfs_1301.bytes[1]);
5939 }
5940
5941 void
pf_state_export(struct pf_state_export * sp,struct pf_kstate * st)5942 pf_state_export(struct pf_state_export *sp, struct pf_kstate *st)
5943 {
5944 bzero(sp, sizeof(*sp));
5945
5946 sp->version = PF_STATE_VERSION;
5947
5948 /* copy from state key */
5949 sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
5950 sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
5951 sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
5952 sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
5953 sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
5954 sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
5955 sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
5956 sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
5957 sp->proto = st->key[PF_SK_WIRE]->proto;
5958 sp->af = st->key[PF_SK_WIRE]->af;
5959
5960 /* copy from state */
5961 strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
5962 strlcpy(sp->orig_ifname, st->orig_kif->pfik_name,
5963 sizeof(sp->orig_ifname));
5964 memcpy(&sp->rt_addr, &st->act.rt_addr, sizeof(sp->rt_addr));
5965 sp->creation = htonl(time_uptime - (st->creation / 1000));
5966 sp->expire = pf_state_expires(st);
5967 if (sp->expire <= time_uptime)
5968 sp->expire = htonl(0);
5969 else
5970 sp->expire = htonl(sp->expire - time_uptime);
5971
5972 sp->direction = st->direction;
5973 sp->log = st->act.log;
5974 sp->timeout = st->timeout;
5975 /* 8 bits for the old libpfctl, 16 bits for the new libpfctl */
5976 sp->state_flags_compat = st->state_flags;
5977 sp->state_flags = htons(st->state_flags);
5978 if (st->sns[PF_SN_LIMIT] != NULL)
5979 sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
5980 if (st->sns[PF_SN_NAT] != NULL || st->sns[PF_SN_ROUTE] != NULL)
5981 sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
5982 sp->id = st->id;
5983 sp->creatorid = st->creatorid;
5984 pf_state_peer_hton(&st->src, &sp->src);
5985 pf_state_peer_hton(&st->dst, &sp->dst);
5986
5987 if (st->rule == NULL)
5988 sp->rule = htonl(-1);
5989 else
5990 sp->rule = htonl(st->rule->nr);
5991 if (st->anchor == NULL)
5992 sp->anchor = htonl(-1);
5993 else
5994 sp->anchor = htonl(st->anchor->nr);
5995 if (st->nat_rule == NULL)
5996 sp->nat_rule = htonl(-1);
5997 else
5998 sp->nat_rule = htonl(st->nat_rule->nr);
5999
6000 sp->packets[0] = st->packets[0];
6001 sp->packets[1] = st->packets[1];
6002 sp->bytes[0] = st->bytes[0];
6003 sp->bytes[1] = st->bytes[1];
6004
6005 sp->qid = htons(st->act.qid);
6006 sp->pqid = htons(st->act.pqid);
6007 sp->dnpipe = htons(st->act.dnpipe);
6008 sp->dnrpipe = htons(st->act.dnrpipe);
6009 sp->rtableid = htonl(st->act.rtableid);
6010 sp->min_ttl = st->act.min_ttl;
6011 sp->set_tos = st->act.set_tos;
6012 sp->max_mss = htons(st->act.max_mss);
6013 sp->rt = st->act.rt;
6014 if (st->act.rt_kif)
6015 strlcpy(sp->rt_ifname, st->act.rt_kif->pfik_name,
6016 sizeof(sp->rt_ifname));
6017 sp->set_prio[0] = st->act.set_prio[0];
6018 sp->set_prio[1] = st->act.set_prio[1];
6019
6020 }
6021
6022 static void
pf_tbladdr_copyout(struct pf_addr_wrap * aw)6023 pf_tbladdr_copyout(struct pf_addr_wrap *aw)
6024 {
6025 struct pfr_ktable *kt;
6026
6027 KASSERT(aw->type == PF_ADDR_TABLE, ("%s: type %u", __func__, aw->type));
6028
6029 kt = aw->p.tbl;
6030 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
6031 kt = kt->pfrkt_root;
6032 aw->p.tbl = NULL;
6033 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
6034 kt->pfrkt_cnt : -1;
6035 }
6036
6037 static int
pf_add_status_counters(nvlist_t * nvl,const char * name,counter_u64_t * counters,size_t number,char ** names)6038 pf_add_status_counters(nvlist_t *nvl, const char *name, counter_u64_t *counters,
6039 size_t number, char **names)
6040 {
6041 nvlist_t *nvc;
6042
6043 nvc = nvlist_create(0);
6044 if (nvc == NULL)
6045 return (ENOMEM);
6046
6047 for (int i = 0; i < number; i++) {
6048 nvlist_append_number_array(nvc, "counters",
6049 counter_u64_fetch(counters[i]));
6050 nvlist_append_string_array(nvc, "names",
6051 names[i]);
6052 nvlist_append_number_array(nvc, "ids",
6053 i);
6054 }
6055 nvlist_add_nvlist(nvl, name, nvc);
6056 nvlist_destroy(nvc);
6057
6058 return (0);
6059 }
6060
6061 static int
pf_getstatus(struct pfioc_nv * nv)6062 pf_getstatus(struct pfioc_nv *nv)
6063 {
6064 nvlist_t *nvl = NULL, *nvc = NULL;
6065 void *nvlpacked = NULL;
6066 int error;
6067 struct pf_status s;
6068 char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
6069 char *pf_lcounter[KLCNT_MAX+1] = KLCNT_NAMES;
6070 char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES;
6071 time_t since;
6072
6073 PF_RULES_RLOCK_TRACKER;
6074
6075 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
6076
6077 PF_RULES_RLOCK();
6078
6079 nvl = nvlist_create(0);
6080 if (nvl == NULL)
6081 ERROUT(ENOMEM);
6082
6083 since = time_second - (time_uptime - V_pf_status.since);
6084
6085 nvlist_add_bool(nvl, "running", V_pf_status.running);
6086 nvlist_add_number(nvl, "since", since);
6087 nvlist_add_number(nvl, "debug", V_pf_status.debug);
6088 nvlist_add_number(nvl, "hostid", V_pf_status.hostid);
6089 nvlist_add_number(nvl, "states", V_pf_status.states);
6090 nvlist_add_number(nvl, "src_nodes", V_pf_status.src_nodes);
6091 nvlist_add_number(nvl, "reass", V_pf_status.reass);
6092 nvlist_add_bool(nvl, "syncookies_active",
6093 V_pf_status.syncookies_active);
6094 nvlist_add_number(nvl, "halfopen_states", V_pf_status.states_halfopen);
6095
6096 /* counters */
6097 error = pf_add_status_counters(nvl, "counters", V_pf_status.counters,
6098 PFRES_MAX, pf_reasons);
6099 if (error != 0)
6100 ERROUT(error);
6101
6102 /* lcounters */
6103 error = pf_add_status_counters(nvl, "lcounters", V_pf_status.lcounters,
6104 KLCNT_MAX, pf_lcounter);
6105 if (error != 0)
6106 ERROUT(error);
6107
6108 /* fcounters */
6109 nvc = nvlist_create(0);
6110 if (nvc == NULL)
6111 ERROUT(ENOMEM);
6112
6113 for (int i = 0; i < FCNT_MAX; i++) {
6114 nvlist_append_number_array(nvc, "counters",
6115 pf_counter_u64_fetch(&V_pf_status.fcounters[i]));
6116 nvlist_append_string_array(nvc, "names",
6117 pf_fcounter[i]);
6118 nvlist_append_number_array(nvc, "ids",
6119 i);
6120 }
6121 nvlist_add_nvlist(nvl, "fcounters", nvc);
6122 nvlist_destroy(nvc);
6123 nvc = NULL;
6124
6125 /* scounters */
6126 error = pf_add_status_counters(nvl, "scounters", V_pf_status.scounters,
6127 SCNT_MAX, pf_fcounter);
6128 if (error != 0)
6129 ERROUT(error);
6130
6131 nvlist_add_string(nvl, "ifname", V_pf_status.ifname);
6132 nvlist_add_binary(nvl, "chksum", V_pf_status.pf_chksum,
6133 PF_MD5_DIGEST_LENGTH);
6134
6135 pfi_update_status(V_pf_status.ifname, &s);
6136
6137 /* pcounters / bcounters */
6138 for (int i = 0; i < 2; i++) {
6139 for (int j = 0; j < 2; j++) {
6140 for (int k = 0; k < 2; k++) {
6141 nvlist_append_number_array(nvl, "pcounters",
6142 s.pcounters[i][j][k]);
6143 }
6144 nvlist_append_number_array(nvl, "bcounters",
6145 s.bcounters[i][j]);
6146 }
6147 }
6148
6149 nvlpacked = nvlist_pack(nvl, &nv->len);
6150 if (nvlpacked == NULL)
6151 ERROUT(ENOMEM);
6152
6153 if (nv->size == 0)
6154 ERROUT(0);
6155 else if (nv->size < nv->len)
6156 ERROUT(ENOSPC);
6157
6158 PF_RULES_RUNLOCK();
6159 error = copyout(nvlpacked, nv->data, nv->len);
6160 goto done;
6161
6162 #undef ERROUT
6163 errout:
6164 PF_RULES_RUNLOCK();
6165 done:
6166 free(nvlpacked, M_NVLIST);
6167 nvlist_destroy(nvc);
6168 nvlist_destroy(nvl);
6169
6170 return (error);
6171 }
6172
6173 /*
6174 * XXX - Check for version mismatch!!!
6175 */
6176 static void
pf_clear_all_states(void)6177 pf_clear_all_states(void)
6178 {
6179 struct epoch_tracker et;
6180 struct pf_kstate *s;
6181 u_int i;
6182
6183 NET_EPOCH_ENTER(et);
6184 for (i = 0; i <= V_pf_hashmask; i++) {
6185 struct pf_idhash *ih = &V_pf_idhash[i];
6186 relock:
6187 PF_HASHROW_LOCK(ih);
6188 LIST_FOREACH(s, &ih->states, entry) {
6189 s->timeout = PFTM_PURGE;
6190 /* Don't send out individual delete messages. */
6191 s->state_flags |= PFSTATE_NOSYNC;
6192 pf_remove_state(s);
6193 goto relock;
6194 }
6195 PF_HASHROW_UNLOCK(ih);
6196 }
6197 NET_EPOCH_EXIT(et);
6198 }
6199
6200 static int
pf_clear_tables(void)6201 pf_clear_tables(void)
6202 {
6203 struct pfioc_table io;
6204 int error;
6205
6206 bzero(&io, sizeof(io));
6207 io.pfrio_flags |= PFR_FLAG_ALLRSETS;
6208
6209 error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel,
6210 io.pfrio_flags);
6211
6212 return (error);
6213 }
6214
6215 static void
pf_kill_srcnodes(struct pfioc_src_node_kill * psnk)6216 pf_kill_srcnodes(struct pfioc_src_node_kill *psnk)
6217 {
6218 struct pf_ksrc_node_list kill;
6219 u_int killed;
6220
6221 LIST_INIT(&kill);
6222 for (int i = 0; i <= V_pf_srchashmask; i++) {
6223 struct pf_srchash *sh = &V_pf_srchash[i];
6224 struct pf_ksrc_node *sn, *tmp;
6225
6226 PF_HASHROW_LOCK(sh);
6227 LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)
6228 if (psnk == NULL ||
6229 (pf_match_addr(psnk->psnk_src.neg,
6230 &psnk->psnk_src.addr.v.a.addr,
6231 &psnk->psnk_src.addr.v.a.mask,
6232 &sn->addr, sn->af) &&
6233 pf_match_addr(psnk->psnk_dst.neg,
6234 &psnk->psnk_dst.addr.v.a.addr,
6235 &psnk->psnk_dst.addr.v.a.mask,
6236 &sn->raddr, sn->af))) {
6237 pf_unlink_src_node(sn);
6238 LIST_INSERT_HEAD(&kill, sn, entry);
6239 sn->expire = 1;
6240 }
6241 PF_HASHROW_UNLOCK(sh);
6242 }
6243
6244 for (int i = 0; i <= V_pf_hashmask; i++) {
6245 struct pf_idhash *ih = &V_pf_idhash[i];
6246 struct pf_kstate *s;
6247
6248 PF_HASHROW_LOCK(ih);
6249 LIST_FOREACH(s, &ih->states, entry) {
6250 for(pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX;
6251 sn_type++) {
6252 if (s->sns[sn_type] &&
6253 s->sns[sn_type]->expire == 1) {
6254 s->sns[sn_type] = NULL;
6255 }
6256 }
6257 }
6258 PF_HASHROW_UNLOCK(ih);
6259 }
6260
6261 killed = pf_free_src_nodes(&kill);
6262
6263 if (psnk != NULL)
6264 psnk->psnk_killed = killed;
6265 }
6266
6267 static int
pf_keepcounters(struct pfioc_nv * nv)6268 pf_keepcounters(struct pfioc_nv *nv)
6269 {
6270 nvlist_t *nvl = NULL;
6271 void *nvlpacked = NULL;
6272 int error = 0;
6273
6274 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
6275
6276 if (nv->len > pf_ioctl_maxcount)
6277 ERROUT(ENOMEM);
6278
6279 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6280 error = copyin(nv->data, nvlpacked, nv->len);
6281 if (error)
6282 ERROUT(error);
6283
6284 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6285 if (nvl == NULL)
6286 ERROUT(EBADMSG);
6287
6288 if (! nvlist_exists_bool(nvl, "keep_counters"))
6289 ERROUT(EBADMSG);
6290
6291 V_pf_status.keep_counters = nvlist_get_bool(nvl, "keep_counters");
6292
6293 on_error:
6294 nvlist_destroy(nvl);
6295 free(nvlpacked, M_NVLIST);
6296 return (error);
6297 }
6298
6299 unsigned int
pf_clear_states(const struct pf_kstate_kill * kill)6300 pf_clear_states(const struct pf_kstate_kill *kill)
6301 {
6302 struct pf_state_key_cmp match_key;
6303 struct pf_kstate *s;
6304 struct pfi_kkif *kif;
6305 int idx;
6306 unsigned int killed = 0, dir;
6307
6308 NET_EPOCH_ASSERT();
6309
6310 for (unsigned int i = 0; i <= V_pf_hashmask; i++) {
6311 struct pf_idhash *ih = &V_pf_idhash[i];
6312
6313 relock_DIOCCLRSTATES:
6314 PF_HASHROW_LOCK(ih);
6315 LIST_FOREACH(s, &ih->states, entry) {
6316 /* For floating states look at the original kif. */
6317 kif = s->kif == V_pfi_all ? s->orig_kif : s->kif;
6318
6319 if (kill->psk_ifname[0] &&
6320 strcmp(kill->psk_ifname,
6321 kif->pfik_name))
6322 continue;
6323
6324 if (kill->psk_kill_match) {
6325 bzero(&match_key, sizeof(match_key));
6326
6327 if (s->direction == PF_OUT) {
6328 dir = PF_IN;
6329 idx = PF_SK_STACK;
6330 } else {
6331 dir = PF_OUT;
6332 idx = PF_SK_WIRE;
6333 }
6334
6335 match_key.af = s->key[idx]->af;
6336 match_key.proto = s->key[idx]->proto;
6337 pf_addrcpy(&match_key.addr[0],
6338 &s->key[idx]->addr[1], match_key.af);
6339 match_key.port[0] = s->key[idx]->port[1];
6340 pf_addrcpy(&match_key.addr[1],
6341 &s->key[idx]->addr[0], match_key.af);
6342 match_key.port[1] = s->key[idx]->port[0];
6343 }
6344
6345 /*
6346 * Don't send out individual
6347 * delete messages.
6348 */
6349 s->state_flags |= PFSTATE_NOSYNC;
6350 pf_remove_state(s);
6351 killed++;
6352
6353 if (kill->psk_kill_match)
6354 killed += pf_kill_matching_state(&match_key,
6355 dir);
6356
6357 goto relock_DIOCCLRSTATES;
6358 }
6359 PF_HASHROW_UNLOCK(ih);
6360 }
6361
6362 if (V_pfsync_clear_states_ptr != NULL)
6363 V_pfsync_clear_states_ptr(V_pf_status.hostid, kill->psk_ifname);
6364
6365 return (killed);
6366 }
6367
6368 void
pf_killstates(struct pf_kstate_kill * kill,unsigned int * killed)6369 pf_killstates(struct pf_kstate_kill *kill, unsigned int *killed)
6370 {
6371 struct pf_kstate *s;
6372
6373 NET_EPOCH_ASSERT();
6374 if (kill->psk_pfcmp.id) {
6375 if (kill->psk_pfcmp.creatorid == 0)
6376 kill->psk_pfcmp.creatorid = V_pf_status.hostid;
6377 if ((s = pf_find_state_byid(kill->psk_pfcmp.id,
6378 kill->psk_pfcmp.creatorid))) {
6379 pf_remove_state(s);
6380 *killed = 1;
6381 }
6382 return;
6383 }
6384
6385 for (unsigned int i = 0; i <= V_pf_hashmask; i++)
6386 *killed += pf_killstates_row(kill, &V_pf_idhash[i]);
6387 }
6388
6389 static int
pf_killstates_nv(struct pfioc_nv * nv)6390 pf_killstates_nv(struct pfioc_nv *nv)
6391 {
6392 struct pf_kstate_kill kill;
6393 struct epoch_tracker et;
6394 nvlist_t *nvl = NULL;
6395 void *nvlpacked = NULL;
6396 int error = 0;
6397 unsigned int killed = 0;
6398
6399 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
6400
6401 if (nv->len > pf_ioctl_maxcount)
6402 ERROUT(ENOMEM);
6403
6404 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6405 error = copyin(nv->data, nvlpacked, nv->len);
6406 if (error)
6407 ERROUT(error);
6408
6409 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6410 if (nvl == NULL)
6411 ERROUT(EBADMSG);
6412
6413 error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
6414 if (error)
6415 ERROUT(error);
6416
6417 NET_EPOCH_ENTER(et);
6418 pf_killstates(&kill, &killed);
6419 NET_EPOCH_EXIT(et);
6420
6421 free(nvlpacked, M_NVLIST);
6422 nvlpacked = NULL;
6423 nvlist_destroy(nvl);
6424 nvl = nvlist_create(0);
6425 if (nvl == NULL)
6426 ERROUT(ENOMEM);
6427
6428 nvlist_add_number(nvl, "killed", killed);
6429
6430 nvlpacked = nvlist_pack(nvl, &nv->len);
6431 if (nvlpacked == NULL)
6432 ERROUT(ENOMEM);
6433
6434 if (nv->size == 0)
6435 ERROUT(0);
6436 else if (nv->size < nv->len)
6437 ERROUT(ENOSPC);
6438
6439 error = copyout(nvlpacked, nv->data, nv->len);
6440
6441 on_error:
6442 nvlist_destroy(nvl);
6443 free(nvlpacked, M_NVLIST);
6444 return (error);
6445 }
6446
6447 static int
pf_clearstates_nv(struct pfioc_nv * nv)6448 pf_clearstates_nv(struct pfioc_nv *nv)
6449 {
6450 struct pf_kstate_kill kill;
6451 struct epoch_tracker et;
6452 nvlist_t *nvl = NULL;
6453 void *nvlpacked = NULL;
6454 int error = 0;
6455 unsigned int killed;
6456
6457 #define ERROUT(x) ERROUT_FUNCTION(on_error, x)
6458
6459 if (nv->len > pf_ioctl_maxcount)
6460 ERROUT(ENOMEM);
6461
6462 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6463 error = copyin(nv->data, nvlpacked, nv->len);
6464 if (error)
6465 ERROUT(error);
6466
6467 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6468 if (nvl == NULL)
6469 ERROUT(EBADMSG);
6470
6471 error = pf_nvstate_kill_to_kstate_kill(nvl, &kill);
6472 if (error)
6473 ERROUT(error);
6474
6475 NET_EPOCH_ENTER(et);
6476 killed = pf_clear_states(&kill);
6477 NET_EPOCH_EXIT(et);
6478
6479 free(nvlpacked, M_NVLIST);
6480 nvlpacked = NULL;
6481 nvlist_destroy(nvl);
6482 nvl = nvlist_create(0);
6483 if (nvl == NULL)
6484 ERROUT(ENOMEM);
6485
6486 nvlist_add_number(nvl, "killed", killed);
6487
6488 nvlpacked = nvlist_pack(nvl, &nv->len);
6489 if (nvlpacked == NULL)
6490 ERROUT(ENOMEM);
6491
6492 if (nv->size == 0)
6493 ERROUT(0);
6494 else if (nv->size < nv->len)
6495 ERROUT(ENOSPC);
6496
6497 error = copyout(nvlpacked, nv->data, nv->len);
6498
6499 #undef ERROUT
6500 on_error:
6501 nvlist_destroy(nvl);
6502 free(nvlpacked, M_NVLIST);
6503 return (error);
6504 }
6505
6506 static int
pf_getstate(struct pfioc_nv * nv)6507 pf_getstate(struct pfioc_nv *nv)
6508 {
6509 nvlist_t *nvl = NULL, *nvls;
6510 void *nvlpacked = NULL;
6511 struct pf_kstate *s = NULL;
6512 int error = 0;
6513 uint64_t id, creatorid;
6514
6515 #define ERROUT(x) ERROUT_FUNCTION(errout, x)
6516
6517 if (nv->len > pf_ioctl_maxcount)
6518 ERROUT(ENOMEM);
6519
6520 nvlpacked = malloc(nv->len, M_NVLIST, M_WAITOK);
6521 error = copyin(nv->data, nvlpacked, nv->len);
6522 if (error)
6523 ERROUT(error);
6524
6525 nvl = nvlist_unpack(nvlpacked, nv->len, 0);
6526 if (nvl == NULL)
6527 ERROUT(EBADMSG);
6528
6529 PFNV_CHK(pf_nvuint64(nvl, "id", &id));
6530 PFNV_CHK(pf_nvuint64(nvl, "creatorid", &creatorid));
6531
6532 s = pf_find_state_byid(id, creatorid);
6533 if (s == NULL)
6534 ERROUT(ENOENT);
6535
6536 free(nvlpacked, M_NVLIST);
6537 nvlpacked = NULL;
6538 nvlist_destroy(nvl);
6539 nvl = nvlist_create(0);
6540 if (nvl == NULL)
6541 ERROUT(ENOMEM);
6542
6543 nvls = pf_state_to_nvstate(s);
6544 if (nvls == NULL)
6545 ERROUT(ENOMEM);
6546
6547 nvlist_add_nvlist(nvl, "state", nvls);
6548 nvlist_destroy(nvls);
6549
6550 nvlpacked = nvlist_pack(nvl, &nv->len);
6551 if (nvlpacked == NULL)
6552 ERROUT(ENOMEM);
6553
6554 if (nv->size == 0)
6555 ERROUT(0);
6556 else if (nv->size < nv->len)
6557 ERROUT(ENOSPC);
6558
6559 error = copyout(nvlpacked, nv->data, nv->len);
6560
6561 #undef ERROUT
6562 errout:
6563 if (s != NULL)
6564 PF_STATE_UNLOCK(s);
6565 free(nvlpacked, M_NVLIST);
6566 nvlist_destroy(nvl);
6567 return (error);
6568 }
6569
6570 /*
6571 * XXX - Check for version mismatch!!!
6572 */
6573
6574 /*
6575 * Duplicate pfctl -Fa operation to get rid of as much as we can.
6576 */
6577 static int
shutdown_pf(void)6578 shutdown_pf(void)
6579 {
6580 int error = 0;
6581 u_int32_t t[5];
6582 char nn = '\0';
6583 struct pf_kanchor *anchor, *tmp_anchor;
6584 struct pf_keth_anchor *eth_anchor, *tmp_eth_anchor;
6585 int rs_num;
6586
6587 do {
6588 /* Unlink rules of all user defined anchors */
6589 RB_FOREACH_SAFE(anchor, pf_kanchor_global, &V_pf_anchors,
6590 tmp_anchor) {
6591 for (rs_num = 0; rs_num < PF_RULESET_MAX; ++rs_num) {
6592 if ((error = pf_begin_rules(&t[rs_num], rs_num,
6593 anchor->path)) != 0) {
6594 DPFPRINTF(PF_DEBUG_MISC, "%s: "
6595 "anchor.path=%s rs_num=%d",
6596 __func__, anchor->path, rs_num);
6597 goto error; /* XXX: rollback? */
6598 }
6599 }
6600 for (rs_num = 0; rs_num < PF_RULESET_MAX; ++rs_num) {
6601 error = pf_commit_rules(t[rs_num], rs_num,
6602 anchor->path);
6603 MPASS(error == 0);
6604 }
6605 }
6606
6607 /* Unlink rules of all user defined ether anchors */
6608 RB_FOREACH_SAFE(eth_anchor, pf_keth_anchor_global,
6609 &V_pf_keth_anchors, tmp_eth_anchor) {
6610 if ((error = pf_begin_eth(&t[0], eth_anchor->path))
6611 != 0) {
6612 DPFPRINTF(PF_DEBUG_MISC, "%s: eth "
6613 "anchor.path=%s", __func__,
6614 eth_anchor->path);
6615 goto error;
6616 }
6617 error = pf_commit_eth(t[0], eth_anchor->path);
6618 MPASS(error == 0);
6619 }
6620
6621 if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
6622 != 0) {
6623 DPFPRINTF(PF_DEBUG_MISC, "%s: SCRUB", __func__);
6624 break;
6625 }
6626 if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
6627 != 0) {
6628 DPFPRINTF(PF_DEBUG_MISC, "%s: FILTER", __func__);
6629 break; /* XXX: rollback? */
6630 }
6631 if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
6632 != 0) {
6633 DPFPRINTF(PF_DEBUG_MISC, "%s: NAT", __func__);
6634 break; /* XXX: rollback? */
6635 }
6636 if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
6637 != 0) {
6638 DPFPRINTF(PF_DEBUG_MISC, "%s: BINAT", __func__);
6639 break; /* XXX: rollback? */
6640 }
6641 if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
6642 != 0) {
6643 DPFPRINTF(PF_DEBUG_MISC, "%s: RDR", __func__);
6644 break; /* XXX: rollback? */
6645 }
6646
6647 error = pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
6648 MPASS(error == 0);
6649 error = pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
6650 MPASS(error == 0);
6651 error = pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
6652 MPASS(error == 0);
6653 error = pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
6654 MPASS(error == 0);
6655 error = pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
6656 MPASS(error == 0);
6657
6658 if ((error = pf_clear_tables()) != 0)
6659 break;
6660
6661 if ((error = pf_begin_eth(&t[0], &nn)) != 0) {
6662 DPFPRINTF(PF_DEBUG_MISC, "%s: eth", __func__);
6663 break;
6664 }
6665 error = pf_commit_eth(t[0], &nn);
6666 MPASS(error == 0);
6667
6668 #ifdef ALTQ
6669 if ((error = pf_begin_altq(&t[0])) != 0) {
6670 DPFPRINTF(PF_DEBUG_MISC, "%s: ALTQ", __func__);
6671 break;
6672 }
6673 pf_commit_altq(t[0]);
6674 #endif
6675
6676 pf_clear_all_states();
6677
6678 pf_kill_srcnodes(NULL);
6679
6680 for (int i = 0; i < PF_RULESET_MAX; i++) {
6681 pf_rule_tree_free(pf_main_ruleset.rules[i].active.tree);
6682 pf_rule_tree_free(pf_main_ruleset.rules[i].inactive.tree);
6683 }
6684
6685 /* status does not use malloced mem so no need to cleanup */
6686 /* fingerprints and interfaces have their own cleanup code */
6687 } while(0);
6688
6689 error:
6690 return (error);
6691 }
6692
6693 static pfil_return_t
pf_check_return(int chk,struct mbuf ** m)6694 pf_check_return(int chk, struct mbuf **m)
6695 {
6696
6697 switch (chk) {
6698 case PF_PASS:
6699 if (*m == NULL)
6700 return (PFIL_CONSUMED);
6701 else
6702 return (PFIL_PASS);
6703 break;
6704 default:
6705 if (*m != NULL) {
6706 m_freem(*m);
6707 *m = NULL;
6708 }
6709 return (PFIL_DROPPED);
6710 }
6711 }
6712
6713 static pfil_return_t
pf_eth_check_in(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)6714 pf_eth_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
6715 void *ruleset __unused, struct inpcb *inp)
6716 {
6717 int chk;
6718
6719 CURVNET_ASSERT_SET();
6720
6721 chk = pf_test_eth(PF_IN, flags, ifp, m, inp);
6722
6723 return (pf_check_return(chk, m));
6724 }
6725
6726 static pfil_return_t
pf_eth_check_out(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)6727 pf_eth_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
6728 void *ruleset __unused, struct inpcb *inp)
6729 {
6730 int chk;
6731
6732 CURVNET_ASSERT_SET();
6733
6734 chk = pf_test_eth(PF_OUT, flags, ifp, m, inp);
6735
6736 return (pf_check_return(chk, m));
6737 }
6738
6739 #ifdef INET
6740 static pfil_return_t
pf_check_in(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)6741 pf_check_in(struct mbuf **m, struct ifnet *ifp, int flags,
6742 void *ruleset __unused, struct inpcb *inp)
6743 {
6744 int chk;
6745
6746 CURVNET_ASSERT_SET();
6747
6748 chk = pf_test(AF_INET, PF_IN, flags, ifp, m, inp, NULL);
6749
6750 return (pf_check_return(chk, m));
6751 }
6752
6753 static pfil_return_t
pf_check_out(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)6754 pf_check_out(struct mbuf **m, struct ifnet *ifp, int flags,
6755 void *ruleset __unused, struct inpcb *inp)
6756 {
6757 int chk;
6758
6759 CURVNET_ASSERT_SET();
6760
6761 chk = pf_test(AF_INET, PF_OUT, flags, ifp, m, inp, NULL);
6762
6763 return (pf_check_return(chk, m));
6764 }
6765 #endif
6766
6767 #ifdef INET6
6768 static pfil_return_t
pf_check6_in(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)6769 pf_check6_in(struct mbuf **m, struct ifnet *ifp, int flags,
6770 void *ruleset __unused, struct inpcb *inp)
6771 {
6772 int chk;
6773
6774 CURVNET_ASSERT_SET();
6775
6776 /*
6777 * In case of loopback traffic IPv6 uses the real interface in
6778 * order to support scoped addresses. In order to support stateful
6779 * filtering we have change this to lo0 as it is the case in IPv4.
6780 */
6781 chk = pf_test(AF_INET6, PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp,
6782 m, inp, NULL);
6783
6784 return (pf_check_return(chk, m));
6785 }
6786
6787 static pfil_return_t
pf_check6_out(struct mbuf ** m,struct ifnet * ifp,int flags,void * ruleset __unused,struct inpcb * inp)6788 pf_check6_out(struct mbuf **m, struct ifnet *ifp, int flags,
6789 void *ruleset __unused, struct inpcb *inp)
6790 {
6791 int chk;
6792
6793 CURVNET_ASSERT_SET();
6794
6795 chk = pf_test(AF_INET6, PF_OUT, flags, ifp, m, inp, NULL);
6796
6797 return (pf_check_return(chk, m));
6798 }
6799 #endif /* INET6 */
6800
6801 VNET_DEFINE_STATIC(pfil_hook_t, pf_eth_in_hook);
6802 VNET_DEFINE_STATIC(pfil_hook_t, pf_eth_out_hook);
6803 #define V_pf_eth_in_hook VNET(pf_eth_in_hook)
6804 #define V_pf_eth_out_hook VNET(pf_eth_out_hook)
6805
6806 #ifdef INET
6807 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_in_hook);
6808 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip4_out_hook);
6809 #define V_pf_ip4_in_hook VNET(pf_ip4_in_hook)
6810 #define V_pf_ip4_out_hook VNET(pf_ip4_out_hook)
6811 #endif
6812 #ifdef INET6
6813 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_in_hook);
6814 VNET_DEFINE_STATIC(pfil_hook_t, pf_ip6_out_hook);
6815 #define V_pf_ip6_in_hook VNET(pf_ip6_in_hook)
6816 #define V_pf_ip6_out_hook VNET(pf_ip6_out_hook)
6817 #endif
6818
6819 static void
hook_pf_eth(void)6820 hook_pf_eth(void)
6821 {
6822 struct pfil_hook_args pha = {
6823 .pa_version = PFIL_VERSION,
6824 .pa_modname = "pf",
6825 .pa_type = PFIL_TYPE_ETHERNET,
6826 };
6827 struct pfil_link_args pla = {
6828 .pa_version = PFIL_VERSION,
6829 };
6830 int ret __diagused;
6831
6832 if (atomic_load_bool(&V_pf_pfil_eth_hooked))
6833 return;
6834
6835 pha.pa_mbuf_chk = pf_eth_check_in;
6836 pha.pa_flags = PFIL_IN;
6837 pha.pa_rulname = "eth-in";
6838 V_pf_eth_in_hook = pfil_add_hook(&pha);
6839 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6840 pla.pa_head = V_link_pfil_head;
6841 pla.pa_hook = V_pf_eth_in_hook;
6842 ret = pfil_link(&pla);
6843 MPASS(ret == 0);
6844 pha.pa_mbuf_chk = pf_eth_check_out;
6845 pha.pa_flags = PFIL_OUT;
6846 pha.pa_rulname = "eth-out";
6847 V_pf_eth_out_hook = pfil_add_hook(&pha);
6848 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6849 pla.pa_head = V_link_pfil_head;
6850 pla.pa_hook = V_pf_eth_out_hook;
6851 ret = pfil_link(&pla);
6852 MPASS(ret == 0);
6853
6854 atomic_store_bool(&V_pf_pfil_eth_hooked, true);
6855 }
6856
6857 static void
hook_pf(void)6858 hook_pf(void)
6859 {
6860 struct pfil_hook_args pha = {
6861 .pa_version = PFIL_VERSION,
6862 .pa_modname = "pf",
6863 };
6864 struct pfil_link_args pla = {
6865 .pa_version = PFIL_VERSION,
6866 };
6867 int ret __diagused;
6868
6869 if (atomic_load_bool(&V_pf_pfil_hooked))
6870 return;
6871
6872 #ifdef INET
6873 pha.pa_type = PFIL_TYPE_IP4;
6874 pha.pa_mbuf_chk = pf_check_in;
6875 pha.pa_flags = PFIL_IN;
6876 pha.pa_rulname = "default-in";
6877 V_pf_ip4_in_hook = pfil_add_hook(&pha);
6878 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6879 pla.pa_head = V_inet_pfil_head;
6880 pla.pa_hook = V_pf_ip4_in_hook;
6881 ret = pfil_link(&pla);
6882 MPASS(ret == 0);
6883 pha.pa_mbuf_chk = pf_check_out;
6884 pha.pa_flags = PFIL_OUT;
6885 pha.pa_rulname = "default-out";
6886 V_pf_ip4_out_hook = pfil_add_hook(&pha);
6887 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6888 pla.pa_head = V_inet_pfil_head;
6889 pla.pa_hook = V_pf_ip4_out_hook;
6890 ret = pfil_link(&pla);
6891 MPASS(ret == 0);
6892 if (V_pf_filter_local) {
6893 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6894 pla.pa_head = V_inet_local_pfil_head;
6895 pla.pa_hook = V_pf_ip4_out_hook;
6896 ret = pfil_link(&pla);
6897 MPASS(ret == 0);
6898 }
6899 #endif
6900 #ifdef INET6
6901 pha.pa_type = PFIL_TYPE_IP6;
6902 pha.pa_mbuf_chk = pf_check6_in;
6903 pha.pa_flags = PFIL_IN;
6904 pha.pa_rulname = "default-in6";
6905 V_pf_ip6_in_hook = pfil_add_hook(&pha);
6906 pla.pa_flags = PFIL_IN | PFIL_HEADPTR | PFIL_HOOKPTR;
6907 pla.pa_head = V_inet6_pfil_head;
6908 pla.pa_hook = V_pf_ip6_in_hook;
6909 ret = pfil_link(&pla);
6910 MPASS(ret == 0);
6911 pha.pa_mbuf_chk = pf_check6_out;
6912 pha.pa_rulname = "default-out6";
6913 pha.pa_flags = PFIL_OUT;
6914 V_pf_ip6_out_hook = pfil_add_hook(&pha);
6915 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6916 pla.pa_head = V_inet6_pfil_head;
6917 pla.pa_hook = V_pf_ip6_out_hook;
6918 ret = pfil_link(&pla);
6919 MPASS(ret == 0);
6920 if (V_pf_filter_local) {
6921 pla.pa_flags = PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
6922 pla.pa_head = V_inet6_local_pfil_head;
6923 pla.pa_hook = V_pf_ip6_out_hook;
6924 ret = pfil_link(&pla);
6925 MPASS(ret == 0);
6926 }
6927 #endif
6928
6929 atomic_store_bool(&V_pf_pfil_hooked, true);
6930 }
6931
6932 static void
dehook_pf_eth(void)6933 dehook_pf_eth(void)
6934 {
6935
6936 if (!atomic_load_bool(&V_pf_pfil_eth_hooked))
6937 return;
6938
6939 pfil_remove_hook(V_pf_eth_in_hook);
6940 pfil_remove_hook(V_pf_eth_out_hook);
6941
6942 atomic_store_bool(&V_pf_pfil_eth_hooked, false);
6943 }
6944
6945 static void
dehook_pf(void)6946 dehook_pf(void)
6947 {
6948
6949 if (!atomic_load_bool(&V_pf_pfil_hooked))
6950 return;
6951
6952 #ifdef INET
6953 pfil_remove_hook(V_pf_ip4_in_hook);
6954 pfil_remove_hook(V_pf_ip4_out_hook);
6955 #endif
6956 #ifdef INET6
6957 pfil_remove_hook(V_pf_ip6_in_hook);
6958 pfil_remove_hook(V_pf_ip6_out_hook);
6959 #endif
6960
6961 atomic_store_bool(&V_pf_pfil_hooked, false);
6962 }
6963
6964 static void
pf_load_vnet(void)6965 pf_load_vnet(void)
6966 {
6967 V_pf_tag_z = uma_zcreate("pf tags", sizeof(struct pf_tagname),
6968 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
6969
6970 rm_init_flags(&V_pf_rules_lock, "pf rulesets", RM_RECURSE);
6971 rm_init_flags(&V_pf_tags_lock, "pf tags and queues", RM_RECURSE);
6972 sx_init(&V_pf_ioctl_lock, "pf ioctl");
6973
6974 pf_init_tagset(&V_pf_tags, &pf_rule_tag_hashsize,
6975 PF_RULE_TAG_HASH_SIZE_DEFAULT);
6976 #ifdef ALTQ
6977 pf_init_tagset(&V_pf_qids, &pf_queue_tag_hashsize,
6978 PF_QUEUE_TAG_HASH_SIZE_DEFAULT);
6979 #endif
6980
6981 V_pf_keth = &V_pf_main_keth_anchor.ruleset;
6982
6983 pfattach_vnet();
6984 V_pf_vnet_active = 1;
6985 }
6986
6987 static int
pf_load(void)6988 pf_load(void)
6989 {
6990 int error;
6991
6992 sx_init(&pf_end_lock, "pf end thread");
6993
6994 pf_mtag_initialize();
6995
6996 pf_dev = make_dev(&pf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, PF_NAME);
6997 if (pf_dev == NULL)
6998 return (ENOMEM);
6999
7000 pf_end_threads = 0;
7001 error = kproc_create(pf_purge_thread, NULL, &pf_purge_proc, 0, 0, "pf purge");
7002 if (error != 0)
7003 return (error);
7004
7005 pfi_initialize();
7006
7007 return (0);
7008 }
7009
7010 static void
pf_unload_vnet(void)7011 pf_unload_vnet(void)
7012 {
7013 int ret __diagused;
7014
7015 V_pf_vnet_active = 0;
7016 V_pf_status.running = 0;
7017 dehook_pf();
7018 dehook_pf_eth();
7019
7020 PF_RULES_WLOCK();
7021 pf_syncookies_cleanup();
7022 shutdown_pf();
7023 PF_RULES_WUNLOCK();
7024
7025 ret = swi_remove(V_pf_swi_cookie);
7026 MPASS(ret == 0);
7027 ret = intr_event_destroy(V_pf_swi_ie);
7028 MPASS(ret == 0);
7029
7030 pf_unload_vnet_purge();
7031
7032 pf_normalize_cleanup();
7033 PF_RULES_WLOCK();
7034 pfi_cleanup_vnet();
7035 PF_RULES_WUNLOCK();
7036 pfr_cleanup();
7037 pf_osfp_flush();
7038 pf_cleanup();
7039 if (IS_DEFAULT_VNET(curvnet))
7040 pf_mtag_cleanup();
7041
7042 pf_cleanup_tagset(&V_pf_tags);
7043 #ifdef ALTQ
7044 pf_cleanup_tagset(&V_pf_qids);
7045 #endif
7046 uma_zdestroy(V_pf_tag_z);
7047
7048 #ifdef PF_WANT_32_TO_64_COUNTER
7049 PF_RULES_WLOCK();
7050 LIST_REMOVE(V_pf_kifmarker, pfik_allkiflist);
7051
7052 MPASS(LIST_EMPTY(&V_pf_allkiflist));
7053 MPASS(V_pf_allkifcount == 0);
7054
7055 LIST_REMOVE(&V_pf_default_rule, allrulelist);
7056 V_pf_allrulecount--;
7057 LIST_REMOVE(V_pf_rulemarker, allrulelist);
7058
7059 MPASS(LIST_EMPTY(&V_pf_allrulelist));
7060 MPASS(V_pf_allrulecount == 0);
7061
7062 PF_RULES_WUNLOCK();
7063
7064 free(V_pf_kifmarker, PFI_MTYPE);
7065 free(V_pf_rulemarker, M_PFRULE);
7066 #endif
7067
7068 /* Free counters last as we updated them during shutdown. */
7069 pf_counter_u64_deinit(&V_pf_default_rule.evaluations);
7070 for (int i = 0; i < 2; i++) {
7071 pf_counter_u64_deinit(&V_pf_default_rule.packets[i]);
7072 pf_counter_u64_deinit(&V_pf_default_rule.bytes[i]);
7073 }
7074 counter_u64_free(V_pf_default_rule.states_cur);
7075 counter_u64_free(V_pf_default_rule.states_tot);
7076 for (pf_sn_types_t sn_type=0; sn_type<PF_SN_MAX; sn_type++)
7077 counter_u64_free(V_pf_default_rule.src_nodes[sn_type]);
7078 uma_zfree_pcpu(pf_timestamp_pcpu_zone, V_pf_default_rule.timestamp);
7079
7080 for (int i = 0; i < PFRES_MAX; i++)
7081 counter_u64_free(V_pf_status.counters[i]);
7082 for (int i = 0; i < KLCNT_MAX; i++)
7083 counter_u64_free(V_pf_status.lcounters[i]);
7084 for (int i = 0; i < FCNT_MAX; i++)
7085 pf_counter_u64_deinit(&V_pf_status.fcounters[i]);
7086 for (int i = 0; i < SCNT_MAX; i++)
7087 counter_u64_free(V_pf_status.scounters[i]);
7088 for (int i = 0; i < NCNT_MAX; i++)
7089 counter_u64_free(V_pf_status.ncounters[i]);
7090
7091 rm_destroy(&V_pf_rules_lock);
7092 sx_destroy(&V_pf_ioctl_lock);
7093 }
7094
7095 static void
pf_unload(void * dummy __unused)7096 pf_unload(void *dummy __unused)
7097 {
7098
7099 sx_xlock(&pf_end_lock);
7100 pf_end_threads = 1;
7101 while (pf_end_threads < 2) {
7102 wakeup_one(pf_purge_thread);
7103 sx_sleep(pf_purge_proc, &pf_end_lock, 0, "pftmo", 0);
7104 }
7105 sx_xunlock(&pf_end_lock);
7106
7107 pf_nl_unregister();
7108
7109 if (pf_dev != NULL)
7110 destroy_dev(pf_dev);
7111
7112 pfi_cleanup();
7113
7114 sx_destroy(&pf_end_lock);
7115 }
7116
7117 static void
vnet_pf_init(void * unused __unused)7118 vnet_pf_init(void *unused __unused)
7119 {
7120
7121 pf_load_vnet();
7122 }
7123 VNET_SYSINIT(vnet_pf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
7124 vnet_pf_init, NULL);
7125
7126 static void
vnet_pf_uninit(const void * unused __unused)7127 vnet_pf_uninit(const void *unused __unused)
7128 {
7129
7130 pf_unload_vnet();
7131 }
7132 SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL);
7133 VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
7134 vnet_pf_uninit, NULL);
7135
7136 static int
pf_modevent(module_t mod,int type,void * data)7137 pf_modevent(module_t mod, int type, void *data)
7138 {
7139 int error = 0;
7140
7141 switch(type) {
7142 case MOD_LOAD:
7143 error = pf_load();
7144 pf_nl_register();
7145 break;
7146 case MOD_UNLOAD:
7147 /* Handled in SYSUNINIT(pf_unload) to ensure it's done after
7148 * the vnet_pf_uninit()s */
7149 break;
7150 default:
7151 error = EINVAL;
7152 break;
7153 }
7154
7155 return (error);
7156 }
7157
7158 static moduledata_t pf_mod = {
7159 "pf",
7160 pf_modevent,
7161 0
7162 };
7163
7164 DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
7165 MODULE_DEPEND(pf, netlink, 1, 1, 1);
7166 MODULE_DEPEND(pf, crypto, 1, 1, 1);
7167 MODULE_VERSION(pf, PF_MODVER);
7168