Bug Summary

File:net/pf_if.c
Warning:line 920, column 3
Value stored to 'n' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pf_if.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/net/pf_if.c
1/* $OpenBSD: pf_if.c,v 1.111 2023/06/30 09:58:30 mvs Exp $ */
2
3/*
4 * Copyright 2005 Henning Brauer <henning@openbsd.org>
5 * Copyright 2005 Ryan McBride <mcbride@openbsd.org>
6 * Copyright (c) 2001 Daniel Hartmeier
7 * Copyright (c) 2003 Cedric Berger
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/mbuf.h>
38#include <sys/filio.h>
39#include <sys/socket.h>
40#include <sys/socketvar.h>
41#include <sys/kernel.h>
42#include <sys/device.h>
43#include <sys/time.h>
44#include <sys/pool.h>
45#include <sys/syslog.h>
46
47#include <net/if.h>
48#include <net/if_var.h>
49
50#include <netinet/in.h>
51#include <netinet/ip.h>
52#include <netinet/ip_var.h>
53
54#include <net/pfvar.h>
55
56#include <netinet/ip_icmp.h>
57#include <netinet/tcp.h>
58#include <netinet/udp.h>
59
60#ifdef INET61
61#include <netinet/ip6.h>
62#include <netinet/icmp6.h>
63#endif /* INET6 */
64
65#include <net/pfvar_priv.h>
66
67#define isupper(c)((c) >= 'A' && (c) <= 'Z') ((c) >= 'A' && (c) <= 'Z')
68#define islower(c)((c) >= 'a' && (c) <= 'z') ((c) >= 'a' && (c) <= 'z')
69#define isalpha(c)(((c) >= 'A' && (c) <= 'Z')||((c) >= 'a' &&
(c) <= 'z'))
(isupper(c)((c) >= 'A' && (c) <= 'Z')||islower(c)((c) >= 'a' && (c) <= 'z'))
70
71struct pfi_kif *pfi_all = NULL((void *)0);
72struct pool pfi_addr_pl;
73struct pfi_ifhead pfi_ifs;
74long pfi_update = 1;
75struct pfr_addr *pfi_buffer;
76int pfi_buffer_cnt;
77int pfi_buffer_max;
78
79void pfi_kif_update(struct pfi_kif *);
80void pfi_dynaddr_update(struct pfi_dynaddr *dyn);
81void pfi_table_update(struct pfr_ktable *, struct pfi_kif *,
82 u_int8_t, int);
83void pfi_kifaddr_update(void *);
84void pfi_instance_add(struct ifnet *, u_int8_t, int);
85void pfi_address_add(struct sockaddr *, sa_family_t, u_int8_t);
86int pfi_if_compare(struct pfi_kif *, struct pfi_kif *);
87int pfi_skip_if(const char *, struct pfi_kif *);
88int pfi_unmask(void *);
89void pfi_group_change(const char *);
90
91RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare)void pfi_ifhead_RB_INSERT_COLOR(struct pfi_ifhead *, struct pfi_kif
*); void pfi_ifhead_RB_REMOVE_COLOR(struct pfi_ifhead *, struct
pfi_kif *, struct pfi_kif *); struct pfi_kif *pfi_ifhead_RB_REMOVE
(struct pfi_ifhead *, struct pfi_kif *); struct pfi_kif *pfi_ifhead_RB_INSERT
(struct pfi_ifhead *, struct pfi_kif *); struct pfi_kif *pfi_ifhead_RB_FIND
(struct pfi_ifhead *, struct pfi_kif *); struct pfi_kif *pfi_ifhead_RB_NFIND
(struct pfi_ifhead *, struct pfi_kif *); struct pfi_kif *pfi_ifhead_RB_NEXT
(struct pfi_kif *); struct pfi_kif *pfi_ifhead_RB_PREV(struct
pfi_kif *); struct pfi_kif *pfi_ifhead_RB_MINMAX(struct pfi_ifhead
*, int);
;
92RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare)void pfi_ifhead_RB_INSERT_COLOR(struct pfi_ifhead *head, struct
pfi_kif *elm) { struct pfi_kif *parent, *gparent, *tmp; while
((parent = (elm)->pfik_tree.rbe_parent) && (parent
)->pfik_tree.rbe_color == 1) { gparent = (parent)->pfik_tree
.rbe_parent; if (parent == (gparent)->pfik_tree.rbe_left) {
tmp = (gparent)->pfik_tree.rbe_right; if (tmp && (
tmp)->pfik_tree.rbe_color == 1) { (tmp)->pfik_tree.rbe_color
= 0; do { (parent)->pfik_tree.rbe_color = 0; (gparent)->
pfik_tree.rbe_color = 1; } while (0); elm = gparent; continue
; } if ((parent)->pfik_tree.rbe_right == elm) { do { (tmp)
= (parent)->pfik_tree.rbe_right; if (((parent)->pfik_tree
.rbe_right = (tmp)->pfik_tree.rbe_left)) { ((tmp)->pfik_tree
.rbe_left)->pfik_tree.rbe_parent = (parent); } do {} while
(0); if (((tmp)->pfik_tree.rbe_parent = (parent)->pfik_tree
.rbe_parent)) { if ((parent) == ((parent)->pfik_tree.rbe_parent
)->pfik_tree.rbe_left) ((parent)->pfik_tree.rbe_parent)
->pfik_tree.rbe_left = (tmp); else ((parent)->pfik_tree
.rbe_parent)->pfik_tree.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->pfik_tree.rbe_left = (parent); (parent
)->pfik_tree.rbe_parent = (tmp); do {} while (0); if (((tmp
)->pfik_tree.rbe_parent)) do {} while (0); } while (0); tmp
= parent; parent = elm; elm = tmp; } do { (parent)->pfik_tree
.rbe_color = 0; (gparent)->pfik_tree.rbe_color = 1; } while
(0); do { (tmp) = (gparent)->pfik_tree.rbe_left; if (((gparent
)->pfik_tree.rbe_left = (tmp)->pfik_tree.rbe_right)) { (
(tmp)->pfik_tree.rbe_right)->pfik_tree.rbe_parent = (gparent
); } do {} while (0); if (((tmp)->pfik_tree.rbe_parent = (
gparent)->pfik_tree.rbe_parent)) { if ((gparent) == ((gparent
)->pfik_tree.rbe_parent)->pfik_tree.rbe_left) ((gparent
)->pfik_tree.rbe_parent)->pfik_tree.rbe_left = (tmp); else
((gparent)->pfik_tree.rbe_parent)->pfik_tree.rbe_right
= (tmp); } else (head)->rbh_root = (tmp); (tmp)->pfik_tree
.rbe_right = (gparent); (gparent)->pfik_tree.rbe_parent = (
tmp); do {} while (0); if (((tmp)->pfik_tree.rbe_parent)) do
{} while (0); } while (0); } else { tmp = (gparent)->pfik_tree
.rbe_left; if (tmp && (tmp)->pfik_tree.rbe_color ==
1) { (tmp)->pfik_tree.rbe_color = 0; do { (parent)->pfik_tree
.rbe_color = 0; (gparent)->pfik_tree.rbe_color = 1; } while
(0); elm = gparent; continue; } if ((parent)->pfik_tree.rbe_left
== elm) { do { (tmp) = (parent)->pfik_tree.rbe_left; if (
((parent)->pfik_tree.rbe_left = (tmp)->pfik_tree.rbe_right
)) { ((tmp)->pfik_tree.rbe_right)->pfik_tree.rbe_parent
= (parent); } do {} while (0); if (((tmp)->pfik_tree.rbe_parent
= (parent)->pfik_tree.rbe_parent)) { if ((parent) == ((parent
)->pfik_tree.rbe_parent)->pfik_tree.rbe_left) ((parent)
->pfik_tree.rbe_parent)->pfik_tree.rbe_left = (tmp); else
((parent)->pfik_tree.rbe_parent)->pfik_tree.rbe_right =
(tmp); } else (head)->rbh_root = (tmp); (tmp)->pfik_tree
.rbe_right = (parent); (parent)->pfik_tree.rbe_parent = (tmp
); do {} while (0); if (((tmp)->pfik_tree.rbe_parent)) do {
} while (0); } while (0); tmp = parent; parent = elm; elm = tmp
; } do { (parent)->pfik_tree.rbe_color = 0; (gparent)->
pfik_tree.rbe_color = 1; } while (0); do { (tmp) = (gparent)->
pfik_tree.rbe_right; if (((gparent)->pfik_tree.rbe_right =
(tmp)->pfik_tree.rbe_left)) { ((tmp)->pfik_tree.rbe_left
)->pfik_tree.rbe_parent = (gparent); } do {} while (0); if
(((tmp)->pfik_tree.rbe_parent = (gparent)->pfik_tree.rbe_parent
)) { if ((gparent) == ((gparent)->pfik_tree.rbe_parent)->
pfik_tree.rbe_left) ((gparent)->pfik_tree.rbe_parent)->
pfik_tree.rbe_left = (tmp); else ((gparent)->pfik_tree.rbe_parent
)->pfik_tree.rbe_right = (tmp); } else (head)->rbh_root
= (tmp); (tmp)->pfik_tree.rbe_left = (gparent); (gparent)
->pfik_tree.rbe_parent = (tmp); do {} while (0); if (((tmp
)->pfik_tree.rbe_parent)) do {} while (0); } while (0); } }
(head->rbh_root)->pfik_tree.rbe_color = 0; } void pfi_ifhead_RB_REMOVE_COLOR
(struct pfi_ifhead *head, struct pfi_kif *parent, struct pfi_kif
*elm) { struct pfi_kif *tmp; while ((elm == ((void *)0) || (
elm)->pfik_tree.rbe_color == 0) && elm != (head)->
rbh_root) { if ((parent)->pfik_tree.rbe_left == elm) { tmp
= (parent)->pfik_tree.rbe_right; if ((tmp)->pfik_tree.
rbe_color == 1) { do { (tmp)->pfik_tree.rbe_color = 0; (parent
)->pfik_tree.rbe_color = 1; } while (0); do { (tmp) = (parent
)->pfik_tree.rbe_right; if (((parent)->pfik_tree.rbe_right
= (tmp)->pfik_tree.rbe_left)) { ((tmp)->pfik_tree.rbe_left
)->pfik_tree.rbe_parent = (parent); } do {} while (0); if (
((tmp)->pfik_tree.rbe_parent = (parent)->pfik_tree.rbe_parent
)) { if ((parent) == ((parent)->pfik_tree.rbe_parent)->
pfik_tree.rbe_left) ((parent)->pfik_tree.rbe_parent)->pfik_tree
.rbe_left = (tmp); else ((parent)->pfik_tree.rbe_parent)->
pfik_tree.rbe_right = (tmp); } else (head)->rbh_root = (tmp
); (tmp)->pfik_tree.rbe_left = (parent); (parent)->pfik_tree
.rbe_parent = (tmp); do {} while (0); if (((tmp)->pfik_tree
.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->
pfik_tree.rbe_right; } if (((tmp)->pfik_tree.rbe_left == (
(void *)0) || ((tmp)->pfik_tree.rbe_left)->pfik_tree.rbe_color
== 0) && ((tmp)->pfik_tree.rbe_right == ((void *)
0) || ((tmp)->pfik_tree.rbe_right)->pfik_tree.rbe_color
== 0)) { (tmp)->pfik_tree.rbe_color = 1; elm = parent; parent
= (elm)->pfik_tree.rbe_parent; } else { if ((tmp)->pfik_tree
.rbe_right == ((void *)0) || ((tmp)->pfik_tree.rbe_right)->
pfik_tree.rbe_color == 0) { struct pfi_kif *oleft; if ((oleft
= (tmp)->pfik_tree.rbe_left)) (oleft)->pfik_tree.rbe_color
= 0; (tmp)->pfik_tree.rbe_color = 1; do { (oleft) = (tmp)
->pfik_tree.rbe_left; if (((tmp)->pfik_tree.rbe_left = (
oleft)->pfik_tree.rbe_right)) { ((oleft)->pfik_tree.rbe_right
)->pfik_tree.rbe_parent = (tmp); } do {} while (0); if (((
oleft)->pfik_tree.rbe_parent = (tmp)->pfik_tree.rbe_parent
)) { if ((tmp) == ((tmp)->pfik_tree.rbe_parent)->pfik_tree
.rbe_left) ((tmp)->pfik_tree.rbe_parent)->pfik_tree.rbe_left
= (oleft); else ((tmp)->pfik_tree.rbe_parent)->pfik_tree
.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (
oleft)->pfik_tree.rbe_right = (tmp); (tmp)->pfik_tree.rbe_parent
= (oleft); do {} while (0); if (((oleft)->pfik_tree.rbe_parent
)) do {} while (0); } while (0); tmp = (parent)->pfik_tree
.rbe_right; } (tmp)->pfik_tree.rbe_color = (parent)->pfik_tree
.rbe_color; (parent)->pfik_tree.rbe_color = 0; if ((tmp)->
pfik_tree.rbe_right) ((tmp)->pfik_tree.rbe_right)->pfik_tree
.rbe_color = 0; do { (tmp) = (parent)->pfik_tree.rbe_right
; if (((parent)->pfik_tree.rbe_right = (tmp)->pfik_tree
.rbe_left)) { ((tmp)->pfik_tree.rbe_left)->pfik_tree.rbe_parent
= (parent); } do {} while (0); if (((tmp)->pfik_tree.rbe_parent
= (parent)->pfik_tree.rbe_parent)) { if ((parent) == ((parent
)->pfik_tree.rbe_parent)->pfik_tree.rbe_left) ((parent)
->pfik_tree.rbe_parent)->pfik_tree.rbe_left = (tmp); else
((parent)->pfik_tree.rbe_parent)->pfik_tree.rbe_right =
(tmp); } else (head)->rbh_root = (tmp); (tmp)->pfik_tree
.rbe_left = (parent); (parent)->pfik_tree.rbe_parent = (tmp
); do {} while (0); if (((tmp)->pfik_tree.rbe_parent)) do {
} while (0); } while (0); elm = (head)->rbh_root; break; }
} else { tmp = (parent)->pfik_tree.rbe_left; if ((tmp)->
pfik_tree.rbe_color == 1) { do { (tmp)->pfik_tree.rbe_color
= 0; (parent)->pfik_tree.rbe_color = 1; } while (0); do {
(tmp) = (parent)->pfik_tree.rbe_left; if (((parent)->pfik_tree
.rbe_left = (tmp)->pfik_tree.rbe_right)) { ((tmp)->pfik_tree
.rbe_right)->pfik_tree.rbe_parent = (parent); } do {} while
(0); if (((tmp)->pfik_tree.rbe_parent = (parent)->pfik_tree
.rbe_parent)) { if ((parent) == ((parent)->pfik_tree.rbe_parent
)->pfik_tree.rbe_left) ((parent)->pfik_tree.rbe_parent)
->pfik_tree.rbe_left = (tmp); else ((parent)->pfik_tree
.rbe_parent)->pfik_tree.rbe_right = (tmp); } else (head)->
rbh_root = (tmp); (tmp)->pfik_tree.rbe_right = (parent); (
parent)->pfik_tree.rbe_parent = (tmp); do {} while (0); if
(((tmp)->pfik_tree.rbe_parent)) do {} while (0); } while (
0); tmp = (parent)->pfik_tree.rbe_left; } if (((tmp)->pfik_tree
.rbe_left == ((void *)0) || ((tmp)->pfik_tree.rbe_left)->
pfik_tree.rbe_color == 0) && ((tmp)->pfik_tree.rbe_right
== ((void *)0) || ((tmp)->pfik_tree.rbe_right)->pfik_tree
.rbe_color == 0)) { (tmp)->pfik_tree.rbe_color = 1; elm = parent
; parent = (elm)->pfik_tree.rbe_parent; } else { if ((tmp)
->pfik_tree.rbe_left == ((void *)0) || ((tmp)->pfik_tree
.rbe_left)->pfik_tree.rbe_color == 0) { struct pfi_kif *oright
; if ((oright = (tmp)->pfik_tree.rbe_right)) (oright)->
pfik_tree.rbe_color = 0; (tmp)->pfik_tree.rbe_color = 1; do
{ (oright) = (tmp)->pfik_tree.rbe_right; if (((tmp)->pfik_tree
.rbe_right = (oright)->pfik_tree.rbe_left)) { ((oright)->
pfik_tree.rbe_left)->pfik_tree.rbe_parent = (tmp); } do {}
while (0); if (((oright)->pfik_tree.rbe_parent = (tmp)->
pfik_tree.rbe_parent)) { if ((tmp) == ((tmp)->pfik_tree.rbe_parent
)->pfik_tree.rbe_left) ((tmp)->pfik_tree.rbe_parent)->
pfik_tree.rbe_left = (oright); else ((tmp)->pfik_tree.rbe_parent
)->pfik_tree.rbe_right = (oright); } else (head)->rbh_root
= (oright); (oright)->pfik_tree.rbe_left = (tmp); (tmp)->
pfik_tree.rbe_parent = (oright); do {} while (0); if (((oright
)->pfik_tree.rbe_parent)) do {} while (0); } while (0); tmp
= (parent)->pfik_tree.rbe_left; } (tmp)->pfik_tree.rbe_color
= (parent)->pfik_tree.rbe_color; (parent)->pfik_tree.rbe_color
= 0; if ((tmp)->pfik_tree.rbe_left) ((tmp)->pfik_tree.
rbe_left)->pfik_tree.rbe_color = 0; do { (tmp) = (parent)->
pfik_tree.rbe_left; if (((parent)->pfik_tree.rbe_left = (tmp
)->pfik_tree.rbe_right)) { ((tmp)->pfik_tree.rbe_right)
->pfik_tree.rbe_parent = (parent); } do {} while (0); if (
((tmp)->pfik_tree.rbe_parent = (parent)->pfik_tree.rbe_parent
)) { if ((parent) == ((parent)->pfik_tree.rbe_parent)->
pfik_tree.rbe_left) ((parent)->pfik_tree.rbe_parent)->pfik_tree
.rbe_left = (tmp); else ((parent)->pfik_tree.rbe_parent)->
pfik_tree.rbe_right = (tmp); } else (head)->rbh_root = (tmp
); (tmp)->pfik_tree.rbe_right = (parent); (parent)->pfik_tree
.rbe_parent = (tmp); do {} while (0); if (((tmp)->pfik_tree
.rbe_parent)) do {} while (0); } while (0); elm = (head)->
rbh_root; break; } } } if (elm) (elm)->pfik_tree.rbe_color
= 0; } struct pfi_kif * pfi_ifhead_RB_REMOVE(struct pfi_ifhead
*head, struct pfi_kif *elm) { struct pfi_kif *child, *parent
, *old = elm; int color; if ((elm)->pfik_tree.rbe_left == (
(void *)0)) child = (elm)->pfik_tree.rbe_right; else if ((
elm)->pfik_tree.rbe_right == ((void *)0)) child = (elm)->
pfik_tree.rbe_left; else { struct pfi_kif *left; elm = (elm)->
pfik_tree.rbe_right; while ((left = (elm)->pfik_tree.rbe_left
)) elm = left; child = (elm)->pfik_tree.rbe_right; parent =
(elm)->pfik_tree.rbe_parent; color = (elm)->pfik_tree.
rbe_color; if (child) (child)->pfik_tree.rbe_parent = parent
; if (parent) { if ((parent)->pfik_tree.rbe_left == elm) (
parent)->pfik_tree.rbe_left = child; else (parent)->pfik_tree
.rbe_right = child; do {} while (0); } else (head)->rbh_root
= child; if ((elm)->pfik_tree.rbe_parent == old) parent =
elm; (elm)->pfik_tree = (old)->pfik_tree; if ((old)->
pfik_tree.rbe_parent) { if (((old)->pfik_tree.rbe_parent)->
pfik_tree.rbe_left == old) ((old)->pfik_tree.rbe_parent)->
pfik_tree.rbe_left = elm; else ((old)->pfik_tree.rbe_parent
)->pfik_tree.rbe_right = elm; do {} while (0); } else (head
)->rbh_root = elm; ((old)->pfik_tree.rbe_left)->pfik_tree
.rbe_parent = elm; if ((old)->pfik_tree.rbe_right) ((old)->
pfik_tree.rbe_right)->pfik_tree.rbe_parent = elm; if (parent
) { left = parent; do { do {} while (0); } while ((left = (left
)->pfik_tree.rbe_parent)); } goto color; } parent = (elm)->
pfik_tree.rbe_parent; color = (elm)->pfik_tree.rbe_color; if
(child) (child)->pfik_tree.rbe_parent = parent; if (parent
) { if ((parent)->pfik_tree.rbe_left == elm) (parent)->
pfik_tree.rbe_left = child; else (parent)->pfik_tree.rbe_right
= child; do {} while (0); } else (head)->rbh_root = child
; color: if (color == 0) pfi_ifhead_RB_REMOVE_COLOR(head, parent
, child); return (old); } struct pfi_kif * pfi_ifhead_RB_INSERT
(struct pfi_ifhead *head, struct pfi_kif *elm) { struct pfi_kif
*tmp; struct pfi_kif *parent = ((void *)0); int comp = 0; tmp
= (head)->rbh_root; while (tmp) { parent = tmp; comp = (pfi_if_compare
)(elm, parent); if (comp < 0) tmp = (tmp)->pfik_tree.rbe_left
; else if (comp > 0) tmp = (tmp)->pfik_tree.rbe_right; else
return (tmp); } do { (elm)->pfik_tree.rbe_parent = parent
; (elm)->pfik_tree.rbe_left = (elm)->pfik_tree.rbe_right
= ((void *)0); (elm)->pfik_tree.rbe_color = 1; } while (0
); if (parent != ((void *)0)) { if (comp < 0) (parent)->
pfik_tree.rbe_left = elm; else (parent)->pfik_tree.rbe_right
= elm; do {} while (0); } else (head)->rbh_root = elm; pfi_ifhead_RB_INSERT_COLOR
(head, elm); return (((void *)0)); } struct pfi_kif * pfi_ifhead_RB_FIND
(struct pfi_ifhead *head, struct pfi_kif *elm) { struct pfi_kif
*tmp = (head)->rbh_root; int comp; while (tmp) { comp = pfi_if_compare
(elm, tmp); if (comp < 0) tmp = (tmp)->pfik_tree.rbe_left
; else if (comp > 0) tmp = (tmp)->pfik_tree.rbe_right; else
return (tmp); } return (((void *)0)); } struct pfi_kif * pfi_ifhead_RB_NFIND
(struct pfi_ifhead *head, struct pfi_kif *elm) { struct pfi_kif
*tmp = (head)->rbh_root; struct pfi_kif *res = ((void *)0
); int comp; while (tmp) { comp = pfi_if_compare(elm, tmp); if
(comp < 0) { res = tmp; tmp = (tmp)->pfik_tree.rbe_left
; } else if (comp > 0) tmp = (tmp)->pfik_tree.rbe_right
; else return (tmp); } return (res); } struct pfi_kif * pfi_ifhead_RB_NEXT
(struct pfi_kif *elm) { if ((elm)->pfik_tree.rbe_right) { elm
= (elm)->pfik_tree.rbe_right; while ((elm)->pfik_tree.
rbe_left) elm = (elm)->pfik_tree.rbe_left; } else { if ((elm
)->pfik_tree.rbe_parent && (elm == ((elm)->pfik_tree
.rbe_parent)->pfik_tree.rbe_left)) elm = (elm)->pfik_tree
.rbe_parent; else { while ((elm)->pfik_tree.rbe_parent &&
(elm == ((elm)->pfik_tree.rbe_parent)->pfik_tree.rbe_right
)) elm = (elm)->pfik_tree.rbe_parent; elm = (elm)->pfik_tree
.rbe_parent; } } return (elm); } struct pfi_kif * pfi_ifhead_RB_PREV
(struct pfi_kif *elm) { if ((elm)->pfik_tree.rbe_left) { elm
= (elm)->pfik_tree.rbe_left; while ((elm)->pfik_tree.rbe_right
) elm = (elm)->pfik_tree.rbe_right; } else { if ((elm)->
pfik_tree.rbe_parent && (elm == ((elm)->pfik_tree.
rbe_parent)->pfik_tree.rbe_right)) elm = (elm)->pfik_tree
.rbe_parent; else { while ((elm)->pfik_tree.rbe_parent &&
(elm == ((elm)->pfik_tree.rbe_parent)->pfik_tree.rbe_left
)) elm = (elm)->pfik_tree.rbe_parent; elm = (elm)->pfik_tree
.rbe_parent; } } return (elm); } struct pfi_kif * pfi_ifhead_RB_MINMAX
(struct pfi_ifhead *head, int val) { struct pfi_kif *tmp = (head
)->rbh_root; struct pfi_kif *parent = ((void *)0); while (
tmp) { parent = tmp; if (val < 0) tmp = (tmp)->pfik_tree
.rbe_left; else tmp = (tmp)->pfik_tree.rbe_right; } return
(parent); }
;
93
94#define PFI_BUFFER_MAX0x10000 0x10000
95#define PFI_MTYPE6 M_PF6
96
97struct pfi_kif *
98pfi_kif_alloc(const char *kif_name, int mflags)
99{
100 struct pfi_kif *kif;
101
102 kif = malloc(sizeof(*pfi_all), PFI_MTYPE6, mflags|M_ZERO0x0008);
103 if (kif == NULL((void *)0))
104 return (NULL((void *)0));
105 strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
106 kif->pfik_tzero = gettime();
107 TAILQ_INIT(&kif->pfik_dynaddrs)do { (&kif->pfik_dynaddrs)->tqh_first = ((void *)0)
; (&kif->pfik_dynaddrs)->tqh_last = &(&kif->
pfik_dynaddrs)->tqh_first; } while (0)
;
108
109 if (!strcmp(kif->pfik_name, "any")) {
110 /* both so it works in the ioctl and the regular case */
111 kif->pfik_flags |= PFI_IFLAG_ANY0x0200;
112 kif->pfik_flags_new |= PFI_IFLAG_ANY0x0200;
113 }
114
115 return (kif);
116}
117
118void
119pfi_kif_free(struct pfi_kif *kif)
120{
121 if (kif == NULL((void *)0))
122 return;
123
124 if (kif->pfik_rules || kif->pfik_states || kif->pfik_routes ||
125 kif->pfik_srcnodes || kif->pfik_flagrefs)
126 panic("kif is still alive");
127
128 free(kif, PFI_MTYPE6, sizeof(*kif));
129}
130
131void
132pfi_initialize(void)
133{
134 /*
135 * The first time we arrive here is during kernel boot,
136 * when if_attachsetup() for the first time. No locking
137 * is needed in this case, because it's granted there
138 * is a single thread, which sets pfi_all global var.
139 */
140 if (pfi_all != NULL((void *)0)) /* already initialized */
141 return;
142
143 pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, IPL_SOFTNET0x2, 0,
144 "pfiaddrpl", NULL((void *)0));
145 pfi_buffer_max = 64;
146 pfi_buffer = mallocarray(pfi_buffer_max, sizeof(*pfi_buffer),
147 PFI_MTYPE6, M_WAITOK0x0001);
148
149 pfi_all = pfi_kif_alloc(IFG_ALL"all", M_WAITOK0x0001);
150
151 if (RB_INSERT(pfi_ifhead, &pfi_ifs, pfi_all)pfi_ifhead_RB_INSERT(&pfi_ifs, pfi_all) != NULL((void *)0))
152 panic("IFG_ALL kif found already");
153}
154
155struct pfi_kif *
156pfi_kif_find(const char *kif_name)
157{
158 struct pfi_kif_cmp s;
159
160 PF_ASSERT_LOCKED()do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail(
0x0001UL, rw_status(&pf_lock),__func__); } while (0)
;
161
162 memset(&s, 0, sizeof(s))__builtin_memset((&s), (0), (sizeof(s)));
163 strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name));
164 return (RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s)pfi_ifhead_RB_FIND(&pfi_ifs, (struct pfi_kif *)&s));
165}
166
167struct pfi_kif *
168pfi_kif_get(const char *kif_name, struct pfi_kif **prealloc)
169{
170 struct pfi_kif *kif;
171
172 PF_ASSERT_LOCKED()do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail(
0x0001UL, rw_status(&pf_lock),__func__); } while (0)
;
173
174 if ((kif = pfi_kif_find(kif_name)))
175 return (kif);
176
177 /* create new one */
178 if ((prealloc == NULL((void *)0)) || (*prealloc == NULL((void *)0))) {
179 kif = pfi_kif_alloc(kif_name, M_NOWAIT0x0002);
180 if (kif == NULL((void *)0))
181 return (NULL((void *)0));
182 } else {
183 kif = *prealloc;
184 *prealloc = NULL((void *)0);
185 }
186
187 RB_INSERT(pfi_ifhead, &pfi_ifs, kif)pfi_ifhead_RB_INSERT(&pfi_ifs, kif);
188 return (kif);
189}
190
191void
192pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what)
193{
194 PF_ASSERT_LOCKED()do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail(
0x0001UL, rw_status(&pf_lock),__func__); } while (0)
;
195
196 switch (what) {
197 case PFI_KIF_REF_RULE:
198 kif->pfik_rules++;
199 break;
200 case PFI_KIF_REF_STATE:
201 kif->pfik_states++;
202 break;
203 case PFI_KIF_REF_ROUTE:
204 kif->pfik_routes++;
205 break;
206 case PFI_KIF_REF_SRCNODE:
207 kif->pfik_srcnodes++;
208 break;
209 case PFI_KIF_REF_FLAG:
210 kif->pfik_flagrefs++;
211 break;
212 default:
213 panic("pfi_kif_ref with unknown type");
214 }
215}
216
217void
218pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what)
219{
220 if (kif == NULL((void *)0))
221 return;
222
223 PF_ASSERT_LOCKED()do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail(
0x0001UL, rw_status(&pf_lock),__func__); } while (0)
;
224
225 switch (what) {
226 case PFI_KIF_REF_NONE:
227 break;
228 case PFI_KIF_REF_RULE:
229 if (kif->pfik_rules <= 0) {
230 DPFPRINTF(LOG_ERR,do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): rules refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
231 "pfi_kif_unref (%s): rules refcount <= 0",do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): rules refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
232 kif->pfik_name)do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): rules refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
;
233 return;
234 }
235 kif->pfik_rules--;
236 break;
237 case PFI_KIF_REF_STATE:
238 if (kif->pfik_states <= 0) {
239 DPFPRINTF(LOG_ERR,do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): state refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
240 "pfi_kif_unref (%s): state refcount <= 0",do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): state refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
241 kif->pfik_name)do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): state refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
;
242 return;
243 }
244 kif->pfik_states--;
245 break;
246 case PFI_KIF_REF_ROUTE:
247 if (kif->pfik_routes <= 0) {
248 DPFPRINTF(LOG_ERR,do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): route refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
249 "pfi_kif_unref (%s): route refcount <= 0",do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): route refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
250 kif->pfik_name)do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): route refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
;
251 return;
252 }
253 kif->pfik_routes--;
254 break;
255 case PFI_KIF_REF_SRCNODE:
256 if (kif->pfik_srcnodes <= 0) {
257 DPFPRINTF(LOG_ERR,do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): src-node refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
258 "pfi_kif_unref (%s): src-node refcount <= 0",do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): src-node refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
259 kif->pfik_name)do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): src-node refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
;
260 return;
261 }
262 kif->pfik_srcnodes--;
263 break;
264 case PFI_KIF_REF_FLAG:
265 if (kif->pfik_flagrefs <= 0) {
266 DPFPRINTF(LOG_ERR,do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): flags refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
267 "pfi_kif_unref (%s): flags refcount <= 0",do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): flags refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
268 kif->pfik_name)do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_kif_unref (%s): flags refcount <= 0", kif->pfik_name
); addlog("\n"); } } while (0)
;
269 return;
270 }
271 kif->pfik_flagrefs--;
272 break;
273 default:
274 panic("pfi_kif_unref (%s) with unknown type", kif->pfik_name);
275 }
276
277 if (kif->pfik_ifp != NULL((void *)0) || kif->pfik_group != NULL((void *)0) || kif == pfi_all)
278 return;
279
280 if (kif->pfik_rules || kif->pfik_states || kif->pfik_routes ||
281 kif->pfik_srcnodes || kif->pfik_flagrefs)
282 return;
283
284 RB_REMOVE(pfi_ifhead, &pfi_ifs, kif)pfi_ifhead_RB_REMOVE(&pfi_ifs, kif);
285 free(kif, PFI_MTYPE6, sizeof(*kif));
286}
287
288int
289pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif)
290{
291 struct ifg_list *p;
292
293 if (rule_kif == NULL((void *)0) || rule_kif == packet_kif)
294 return (1);
295
296 if (rule_kif->pfik_group != NULL((void *)0))
297 TAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next)for((p) = ((&packet_kif->pfik_ifp->if_groups)->tqh_first
); (p) != ((void *)0); (p) = ((p)->ifgl_next.tqe_next))
298 if (p->ifgl_group == rule_kif->pfik_group)
299 return (1);
300
301 if (rule_kif->pfik_flags & PFI_IFLAG_ANY0x0200 && packet_kif->pfik_ifp &&
302 !(packet_kif->pfik_ifp->if_flags & IFF_LOOPBACK0x8))
303 return (1);
304
305 return (0);
306}
307
308void
309pfi_attach_ifnet(struct ifnet *ifp)
310{
311 struct pfi_kif *kif;
312 struct task *t;
313
314 PF_LOCK()do { rw_enter_write(&pf_lock); } while (0);
315 pfi_initialize();
316 pfi_update++;
317 if ((kif = pfi_kif_get(ifp->if_xname, NULL((void *)0))) == NULL((void *)0))
318 panic("%s: pfi_kif_get failed", __func__);
319
320 kif->pfik_ifp = ifp;
321 ifp->if_pf_kif = (caddr_t)kif;
322
323 t = malloc(sizeof(*t), PFI_MTYPE6, M_WAITOK0x0001);
324 task_set(t, pfi_kifaddr_update, kif);
325 if_addrhook_add(ifp, t);
326 kif->pfik_ah_cookie = t;
327
328 pfi_kif_update(kif);
329 PF_UNLOCK()do { do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail
(0x0001UL, rw_status(&pf_lock),__func__); } while (0); rw_exit_write
(&pf_lock); } while (0)
;
330}
331
332void
333pfi_detach_ifnet(struct ifnet *ifp)
334{
335 struct pfi_kif *kif;
336 struct task *t;
337
338 if ((kif = (struct pfi_kif *)ifp->if_pf_kif) == NULL((void *)0))
339 return;
340
341 PF_LOCK()do { rw_enter_write(&pf_lock); } while (0);
342 pfi_update++;
343 t = kif->pfik_ah_cookie;
344 kif->pfik_ah_cookie = NULL((void *)0);
345 if_addrhook_del(ifp, t);
346 free(t, PFI_MTYPE6, sizeof(*t));
347
348 pfi_kif_update(kif);
349
350 kif->pfik_ifp = NULL((void *)0);
351 ifp->if_pf_kif = NULL((void *)0);
352 pfi_kif_unref(kif, PFI_KIF_REF_NONE);
353 PF_UNLOCK()do { do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail
(0x0001UL, rw_status(&pf_lock),__func__); } while (0); rw_exit_write
(&pf_lock); } while (0)
;
354}
355
356void
357pfi_attach_ifgroup(struct ifg_group *ifg)
358{
359 struct pfi_kif *kif;
360
361 PF_LOCK()do { rw_enter_write(&pf_lock); } while (0);
362 pfi_initialize();
363 pfi_update++;
364 if ((kif = pfi_kif_get(ifg->ifg_group, NULL((void *)0))) == NULL((void *)0))
365 panic("%s: pfi_kif_get failed", __func__);
366
367 kif->pfik_group = ifg;
368 ifg->ifg_pf_kif = (caddr_t)kif;
369 PF_UNLOCK()do { do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail
(0x0001UL, rw_status(&pf_lock),__func__); } while (0); rw_exit_write
(&pf_lock); } while (0)
;
370}
371
372void
373pfi_detach_ifgroup(struct ifg_group *ifg)
374{
375 struct pfi_kif *kif;
376
377 if ((kif = (struct pfi_kif *)ifg->ifg_pf_kif) == NULL((void *)0))
378 return;
379
380 PF_LOCK()do { rw_enter_write(&pf_lock); } while (0);
381 pfi_update++;
382
383 kif->pfik_group = NULL((void *)0);
384 ifg->ifg_pf_kif = NULL((void *)0);
385 pfi_kif_unref(kif, PFI_KIF_REF_NONE);
386 PF_UNLOCK()do { do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail
(0x0001UL, rw_status(&pf_lock),__func__); } while (0); rw_exit_write
(&pf_lock); } while (0)
;
387}
388
389void
390pfi_group_change(const char *group)
391{
392 struct pfi_kif *kif;
393
394 pfi_update++;
395 if ((kif = pfi_kif_get(group, NULL((void *)0))) == NULL((void *)0))
396 panic("%s: pfi_kif_get failed", __func__);
397
398 pfi_kif_update(kif);
399}
400
401void
402pfi_group_delmember(const char *group)
403{
404 PF_LOCK()do { rw_enter_write(&pf_lock); } while (0);
405 pfi_group_change(group);
406 pfi_xcommit();
407 PF_UNLOCK()do { do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail
(0x0001UL, rw_status(&pf_lock),__func__); } while (0); rw_exit_write
(&pf_lock); } while (0)
;
408}
409
410void
411pfi_group_addmember(const char *group)
412{
413 PF_LOCK()do { rw_enter_write(&pf_lock); } while (0);
414 pfi_group_change(group);
415 pfi_xcommit();
416 PF_UNLOCK()do { do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail
(0x0001UL, rw_status(&pf_lock),__func__); } while (0); rw_exit_write
(&pf_lock); } while (0)
;
417}
418
419int
420pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
421{
422 switch (af) {
423 case AF_INET2:
424 switch (dyn->pfid_acnt4) {
425 case 0:
426 return (0);
427 case 1:
428 return (pf_match_addr(0, &dyn->pfid_addr4,
429 &dyn->pfid_mask4, a, AF_INET2));
430 default:
431 return (pfr_match_addr(dyn->pfid_kt, a, AF_INET2));
432 }
433 break;
434#ifdef INET61
435 case AF_INET624:
436 switch (dyn->pfid_acnt6) {
437 case 0:
438 return (0);
439 case 1:
440 return (pf_match_addr(0, &dyn->pfid_addr6,
441 &dyn->pfid_mask6, a, AF_INET624));
442 default:
443 return (pfr_match_addr(dyn->pfid_kt, a, AF_INET624));
444 }
445 break;
446#endif /* INET6 */
447 default:
448 return (0);
449 }
450}
451
452int
453pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af, int wait)
454{
455 struct pfi_dynaddr *dyn;
456 char tblname[PF_TABLE_NAME_SIZE32];
457 struct pf_ruleset *ruleset = NULL((void *)0);
458 int rv = 0;
459
460 if (aw->type != PF_ADDR_DYNIFTL)
461 return (0);
462 if ((dyn = pool_get(&pfi_addr_pl, wait|PR_LIMITFAIL0x0004|PR_ZERO0x0008)) == NULL((void *)0))
463 return (1);
464
465 if (!strcmp(aw->v.ifname, "self"))
466 dyn->pfid_kif = pfi_kif_get(IFG_ALL"all", NULL((void *)0));
467 else
468 dyn->pfid_kif = pfi_kif_get(aw->v.ifname, NULL((void *)0));
469 if (dyn->pfid_kif == NULL((void *)0)) {
470 rv = 1;
471 goto _bad;
472 }
473 pfi_kif_ref(dyn->pfid_kif, PFI_KIF_REF_RULE);
474
475 dyn->pfid_net = pfi_unmask(&aw->v.a.mask);
476 if (af == AF_INET2 && dyn->pfid_net == 32)
477 dyn->pfid_net = 128;
478 strlcpy(tblname, aw->v.ifname, sizeof(tblname));
479 if (aw->iflags & PFI_AFLAG_NETWORK0x01)
480 strlcat(tblname, ":network", sizeof(tblname));
481 if (aw->iflags & PFI_AFLAG_BROADCAST0x02)
482 strlcat(tblname, ":broadcast", sizeof(tblname));
483 if (aw->iflags & PFI_AFLAG_PEER0x04)
484 strlcat(tblname, ":peer", sizeof(tblname));
485 if (aw->iflags & PFI_AFLAG_NOALIAS0x08)
486 strlcat(tblname, ":0", sizeof(tblname));
487 if (dyn->pfid_net != 128)
488 snprintf(tblname + strlen(tblname),
489 sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net);
490 if ((ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR"_pf")) == NULL((void *)0)) {
491 rv = 1;
492 goto _bad;
493 }
494
495 if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, wait)) == NULL((void *)0)) {
496 rv = 1;
497 goto _bad;
498 }
499
500 dyn->pfid_kt->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags |= PFR_TFLAG_ACTIVE0x00000004;
501 dyn->pfid_iflags = aw->iflags;
502 dyn->pfid_af = af;
503
504 TAILQ_INSERT_TAIL(&dyn->pfid_kif->pfik_dynaddrs, dyn, entry)do { (dyn)->entry.tqe_next = ((void *)0); (dyn)->entry.
tqe_prev = (&dyn->pfid_kif->pfik_dynaddrs)->tqh_last
; *(&dyn->pfid_kif->pfik_dynaddrs)->tqh_last = (
dyn); (&dyn->pfid_kif->pfik_dynaddrs)->tqh_last =
&(dyn)->entry.tqe_next; } while (0)
;
505 aw->p.dyn = dyn;
506 pfi_kif_update(dyn->pfid_kif);
507 return (0);
508
509_bad:
510 if (dyn->pfid_kt != NULL((void *)0))
511 pfr_detach_table(dyn->pfid_kt);
512 if (ruleset != NULL((void *)0))
513 pf_remove_if_empty_ruleset(ruleset);
514 if (dyn->pfid_kif != NULL((void *)0))
515 pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE);
516 pool_put(&pfi_addr_pl, dyn);
517 return (rv);
518}
519
520void
521pfi_kif_update(struct pfi_kif *kif)
522{
523 struct ifg_list *ifgl;
524 struct pfi_dynaddr *p;
525
526 /* update all dynaddr */
527 TAILQ_FOREACH(p, &kif->pfik_dynaddrs, entry)for((p) = ((&kif->pfik_dynaddrs)->tqh_first); (p) !=
((void *)0); (p) = ((p)->entry.tqe_next))
528 pfi_dynaddr_update(p);
529
530 /* again for all groups kif is member of */
531 if (kif->pfik_ifp != NULL((void *)0))
532 TAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_next)for((ifgl) = ((&kif->pfik_ifp->if_groups)->tqh_first
); (ifgl) != ((void *)0); (ifgl) = ((ifgl)->ifgl_next.tqe_next
))
533 pfi_kif_update((struct pfi_kif *)
534 ifgl->ifgl_group->ifg_pf_kif);
535}
536
537void
538pfi_dynaddr_update(struct pfi_dynaddr *dyn)
539{
540 struct pfi_kif *kif;
541 struct pfr_ktable *kt;
542
543 if (dyn == NULL((void *)0) || dyn->pfid_kif == NULL((void *)0) || dyn->pfid_kt == NULL((void *)0))
544 panic("pfi_dynaddr_update");
545
546 kif = dyn->pfid_kif;
547 kt = dyn->pfid_kt;
548
549 if (kt->pfrkt_larg != pfi_update) {
550 /* this table needs to be brought up-to-date */
551 pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags);
552 kt->pfrkt_larg = pfi_update;
553 }
554 pfr_dynaddr_update(kt, dyn);
555}
556
557void
558pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, u_int8_t net, int flags)
559{
560 int e, size2 = 0;
561 struct ifg_member *ifgm;
562
563 pfi_buffer_cnt = 0;
564
565 if (kif->pfik_ifp != NULL((void *)0))
566 pfi_instance_add(kif->pfik_ifp, net, flags);
567 else if (kif->pfik_group != NULL((void *)0))
568 TAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)for((ifgm) = ((&kif->pfik_group->ifg_members)->tqh_first
); (ifgm) != ((void *)0); (ifgm) = ((ifgm)->ifgm_next.tqe_next
))
569 pfi_instance_add(ifgm->ifgm_ifp, net, flags);
570
571 if ((e = pfr_set_addrs(&kt->pfrkt_tpfrkt_ts.pfrts_t, pfi_buffer, pfi_buffer_cnt, &size2,
572 NULL((void *)0), NULL((void *)0), NULL((void *)0), 0, PFR_TFLAG_ALLMASK0x0000007F)))
573 DPFPRINTF(LOG_ERR,do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_table_update: cannot set %d new addresses " "into table %s: %d"
, pfi_buffer_cnt, kt->pfrkt_ts.pfrts_t.pfrt_name, e); addlog
("\n"); } } while (0)
574 "pfi_table_update: cannot set %d new addresses "do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_table_update: cannot set %d new addresses " "into table %s: %d"
, pfi_buffer_cnt, kt->pfrkt_ts.pfrts_t.pfrt_name, e); addlog
("\n"); } } while (0)
575 "into table %s: %d", pfi_buffer_cnt, kt->pfrkt_name, e)do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_table_update: cannot set %d new addresses " "into table %s: %d"
, pfi_buffer_cnt, kt->pfrkt_ts.pfrts_t.pfrt_name, e); addlog
("\n"); } } while (0)
;
576}
577
578void
579pfi_instance_add(struct ifnet *ifp, u_int8_t net, int flags)
580{
581 struct ifaddr *ifa;
582 int got4 = 0, got6 = 0;
583 int net2, af;
584
585 if (ifp == NULL((void *)0))
586 return;
587 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)for((ifa) = ((&ifp->if_addrlist)->tqh_first); (ifa)
!= ((void *)0); (ifa) = ((ifa)->ifa_list.tqe_next))
{
588 if (ifa->ifa_addr == NULL((void *)0))
589 continue;
590 af = ifa->ifa_addr->sa_family;
591 if (af != AF_INET2 && af != AF_INET624)
592 continue;
593 if ((flags & PFI_AFLAG_BROADCAST0x02) && af == AF_INET624)
594 continue;
595 if ((flags & PFI_AFLAG_BROADCAST0x02) &&
596 !(ifp->if_flags & IFF_BROADCAST0x2))
597 continue;
598 if ((flags & PFI_AFLAG_PEER0x04) &&
599 !(ifp->if_flags & IFF_POINTOPOINT0x10))
600 continue;
601 if ((flags & PFI_AFLAG_NETWORK0x01) && af == AF_INET624 &&
602 IN6_IS_ADDR_LINKLOCAL((((&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr
)->__u6_addr.__u6_addr8[0] == 0xfe) && (((&((struct
sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)->__u6_addr
.__u6_addr8[1] & 0xc0) == 0x80))
603 &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)(((&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr
)->__u6_addr.__u6_addr8[0] == 0xfe) && (((&((struct
sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)->__u6_addr
.__u6_addr8[1] & 0xc0) == 0x80))
)
604 continue;
605 if (flags & PFI_AFLAG_NOALIAS0x08) {
606 if (af == AF_INET2 && got4)
607 continue;
608 if (af == AF_INET624 && got6)
609 continue;
610 }
611 if (af == AF_INET2)
612 got4 = 1;
613 else if (af == AF_INET624)
614 got6 = 1;
615 net2 = net;
616 if (net2 == 128 && (flags & PFI_AFLAG_NETWORK0x01)) {
617 if (af == AF_INET2)
618 net2 = pfi_unmask(&((struct sockaddr_in *)
619 ifa->ifa_netmask)->sin_addr);
620 else if (af == AF_INET624)
621 net2 = pfi_unmask(&((struct sockaddr_in6 *)
622 ifa->ifa_netmask)->sin6_addr);
623 }
624 if (af == AF_INET2 && net2 > 32)
625 net2 = 32;
626 if (flags & PFI_AFLAG_BROADCAST0x02)
627 pfi_address_add(ifa->ifa_broadaddrifa_dstaddr, af, net2);
628 else if (flags & PFI_AFLAG_PEER0x04)
629 pfi_address_add(ifa->ifa_dstaddr, af, net2);
630 else
631 pfi_address_add(ifa->ifa_addr, af, net2);
632 }
633}
634
635void
636pfi_address_add(struct sockaddr *sa, sa_family_t af, u_int8_t net)
637{
638 struct pfr_addr *p;
639 int i;
640
641 if (pfi_buffer_cnt >= pfi_buffer_max) {
642 int new_max = pfi_buffer_max * 2;
643
644 if (new_max > PFI_BUFFER_MAX0x10000) {
645 DPFPRINTF(LOG_ERR,do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_address_add: address buffer full (%d/%d)", pfi_buffer_cnt
, 0x10000); addlog("\n"); } } while (0)
646 "pfi_address_add: address buffer full (%d/%d)",do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_address_add: address buffer full (%d/%d)", pfi_buffer_cnt
, 0x10000); addlog("\n"); } } while (0)
647 pfi_buffer_cnt, PFI_BUFFER_MAX)do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_address_add: address buffer full (%d/%d)", pfi_buffer_cnt
, 0x10000); addlog("\n"); } } while (0)
;
648 return;
649 }
650 p = mallocarray(new_max, sizeof(*pfi_buffer), PFI_MTYPE6,
651 M_DONTWAIT0x0002);
652 if (p == NULL((void *)0)) {
653 DPFPRINTF(LOG_ERR,do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_address_add: no memory to grow buffer " "(%d/%d)", pfi_buffer_cnt
, 0x10000); addlog("\n"); } } while (0)
654 "pfi_address_add: no memory to grow buffer "do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_address_add: no memory to grow buffer " "(%d/%d)", pfi_buffer_cnt
, 0x10000); addlog("\n"); } } while (0)
655 "(%d/%d)", pfi_buffer_cnt, PFI_BUFFER_MAX)do { if (pf_status.debug >= (3)) { log(3, "pf: "); addlog(
"pfi_address_add: no memory to grow buffer " "(%d/%d)", pfi_buffer_cnt
, 0x10000); addlog("\n"); } } while (0)
;
656 return;
657 }
658 memcpy(p, pfi_buffer, pfi_buffer_max * sizeof(*pfi_buffer))__builtin_memcpy((p), (pfi_buffer), (pfi_buffer_max * sizeof(
*pfi_buffer)))
;
659 /* no need to zero buffer */
660 free(pfi_buffer, PFI_MTYPE6, pfi_buffer_max * sizeof(*pfi_buffer));
661 pfi_buffer = p;
662 pfi_buffer_max = new_max;
663 }
664 if (af == AF_INET2 && net > 32)
665 net = 128;
666 p = pfi_buffer + pfi_buffer_cnt++;
667 memset(p, 0, sizeof(*p))__builtin_memset((p), (0), (sizeof(*p)));
668 p->pfra_af = af;
669 p->pfra_net = net;
670 if (af == AF_INET2)
671 p->pfra_ip4addrpfra_u._pfra_ip4addr = ((struct sockaddr_in *)sa)->sin_addr;
672 else if (af == AF_INET624) {
673 p->pfra_ip6addrpfra_u._pfra_ip6addr = ((struct sockaddr_in6 *)sa)->sin6_addr;
674 if (IN6_IS_SCOPE_EMBED(&p->pfra_ip6addr)(((((&p->pfra_u._pfra_ip6addr)->__u6_addr.__u6_addr8
[0] == 0xfe) && (((&p->pfra_u._pfra_ip6addr)->
__u6_addr.__u6_addr8[1] & 0xc0) == 0x80))) || ((((&p->
pfra_u._pfra_ip6addr)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&p->pfra_u._pfra_ip6addr)->__u6_addr.__u6_addr8
[1] & 0x0f) == 0x02))) || ((((&p->pfra_u._pfra_ip6addr
)->__u6_addr.__u6_addr8[0] == 0xff) && (((&p->
pfra_u._pfra_ip6addr)->__u6_addr.__u6_addr8[1] & 0x0f)
== 0x01))))
)
675 p->pfra_ip6addrpfra_u._pfra_ip6addr.s6_addr16__u6_addr.__u6_addr16[1] = 0;
676 }
677 /* mask network address bits */
678 if (net < 128)
679 ((caddr_t)p)[p->pfra_net/8] &= ~(0xFF >> (p->pfra_net%8));
680 for (i = (p->pfra_net+7)/8; i < sizeof(p->pfra_u); i++)
681 ((caddr_t)p)[i] = 0;
682}
683
684void
685pfi_dynaddr_remove(struct pf_addr_wrap *aw)
686{
687 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL((void *)0) ||
688 aw->p.dyn->pfid_kif == NULL((void *)0) || aw->p.dyn->pfid_kt == NULL((void *)0))
689 return;
690
691 TAILQ_REMOVE(&aw->p.dyn->pfid_kif->pfik_dynaddrs, aw->p.dyn, entry)do { if (((aw->p.dyn)->entry.tqe_next) != ((void *)0)) (
aw->p.dyn)->entry.tqe_next->entry.tqe_prev = (aw->
p.dyn)->entry.tqe_prev; else (&aw->p.dyn->pfid_kif
->pfik_dynaddrs)->tqh_last = (aw->p.dyn)->entry.tqe_prev
; *(aw->p.dyn)->entry.tqe_prev = (aw->p.dyn)->entry
.tqe_next; ((aw->p.dyn)->entry.tqe_prev) = ((void *)-1)
; ((aw->p.dyn)->entry.tqe_next) = ((void *)-1); } while
(0)
;
692 pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE);
693 aw->p.dyn->pfid_kif = NULL((void *)0);
694 pfr_detach_table(aw->p.dyn->pfid_kt);
695 aw->p.dyn->pfid_kt = NULL((void *)0);
696 pool_put(&pfi_addr_pl, aw->p.dyn);
697 aw->p.dyn = NULL((void *)0);
698}
699
700void
701pfi_dynaddr_copyout(struct pf_addr_wrap *aw)
702{
703 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL((void *)0) ||
704 aw->p.dyn->pfid_kif == NULL((void *)0))
705 return;
706 aw->p.dyncnt = aw->p.dyn->pfid_acnt4 + aw->p.dyn->pfid_acnt6;
707}
708
709void
710pfi_kifaddr_update(void *v)
711{
712 struct pfi_kif *kif = (struct pfi_kif *)v;
713
714 NET_ASSERT_LOCKED()do { int _s = rw_status(&netlock); if ((splassert_ctl >
0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail
(0x0002UL, _s, __func__); } while (0)
;
715
716 PF_LOCK()do { rw_enter_write(&pf_lock); } while (0);
717 pfi_update++;
718 pfi_kif_update(kif);
719 PF_UNLOCK()do { do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail
(0x0001UL, rw_status(&pf_lock),__func__); } while (0); rw_exit_write
(&pf_lock); } while (0)
;
720}
721
722int
723pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
724{
725 return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ16));
726}
727
728void
729pfi_update_status(const char *name, struct pf_status *pfs)
730{
731 struct pfi_kif *p;
732 struct pfi_kif_cmp key;
733 struct ifg_member p_member, *ifgm;
734 TAILQ_HEAD(, ifg_member)struct { struct ifg_member *tqh_first; struct ifg_member **tqh_last
; }
ifg_members;
735 int i, j, k;
736
737 if (*name == '\0' && pfs == NULL((void *)0)) {
738 RB_FOREACH(p, pfi_ifhead, &pfi_ifs)for ((p) = pfi_ifhead_RB_MINMAX(&pfi_ifs, -1); (p) != ((void
*)0); (p) = pfi_ifhead_RB_NEXT(p))
{
739 memset(p->pfik_packets, 0, sizeof(p->pfik_packets))__builtin_memset((p->pfik_packets), (0), (sizeof(p->pfik_packets
)))
;
740 memset(p->pfik_bytes, 0, sizeof(p->pfik_bytes))__builtin_memset((p->pfik_bytes), (0), (sizeof(p->pfik_bytes
)))
;
741 p->pfik_tzero = gettime();
742 }
743 return;
744 }
745
746 strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
747 p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key)pfi_ifhead_RB_FIND(&pfi_ifs, (struct pfi_kif *)&key);
748 if (p == NULL((void *)0)) {
749 return;
750 }
751 if (p->pfik_group != NULL((void *)0)) {
752 memcpy(&ifg_members, &p->pfik_group->ifg_members,__builtin_memcpy((&ifg_members), (&p->pfik_group->
ifg_members), (sizeof(ifg_members)))
753 sizeof(ifg_members))__builtin_memcpy((&ifg_members), (&p->pfik_group->
ifg_members), (sizeof(ifg_members)))
;
754 } else {
755 /* build a temporary list for p only */
756 memset(&p_member, 0, sizeof(p_member))__builtin_memset((&p_member), (0), (sizeof(p_member)));
757 p_member.ifgm_ifp = p->pfik_ifp;
758 TAILQ_INIT(&ifg_members)do { (&ifg_members)->tqh_first = ((void *)0); (&ifg_members
)->tqh_last = &(&ifg_members)->tqh_first; } while
(0)
;
759 TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next)do { (&p_member)->ifgm_next.tqe_next = ((void *)0); (&
p_member)->ifgm_next.tqe_prev = (&ifg_members)->tqh_last
; *(&ifg_members)->tqh_last = (&p_member); (&ifg_members
)->tqh_last = &(&p_member)->ifgm_next.tqe_next;
} while (0)
;
760 }
761 if (pfs) {
762 memset(pfs->pcounters, 0, sizeof(pfs->pcounters))__builtin_memset((pfs->pcounters), (0), (sizeof(pfs->pcounters
)))
;
763 memset(pfs->bcounters, 0, sizeof(pfs->bcounters))__builtin_memset((pfs->bcounters), (0), (sizeof(pfs->bcounters
)))
;
764 }
765 TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next)for((ifgm) = ((&ifg_members)->tqh_first); (ifgm) != ((
void *)0); (ifgm) = ((ifgm)->ifgm_next.tqe_next))
{
766 if (ifgm->ifgm_ifp == NULL((void *)0))
767 continue;
768 p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
769
770 /* just clear statistics */
771 if (pfs == NULL((void *)0)) {
772 memset(p->pfik_packets, 0, sizeof(p->pfik_packets))__builtin_memset((p->pfik_packets), (0), (sizeof(p->pfik_packets
)))
;
773 memset(p->pfik_bytes, 0, sizeof(p->pfik_bytes))__builtin_memset((p->pfik_bytes), (0), (sizeof(p->pfik_bytes
)))
;
774 p->pfik_tzero = gettime();
775 continue;
776 }
777 for (i = 0; i < 2; i++)
778 for (j = 0; j < 2; j++)
779 for (k = 0; k < 2; k++) {
780 pfs->pcounters[i][j][k] +=
781 p->pfik_packets[i][j][k];
782 pfs->bcounters[i][j] +=
783 p->pfik_bytes[i][j][k];
784 }
785 }
786}
787
788void
789pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
790{
791 struct pfi_kif *p;
792 int n = 0;
793
794 RB_FOREACH(p, pfi_ifhead, &pfi_ifs)for ((p) = pfi_ifhead_RB_MINMAX(&pfi_ifs, -1); (p) != ((void
*)0); (p) = pfi_ifhead_RB_NEXT(p))
{
795 if (pfi_skip_if(name, p))
796 continue;
797 if (*size <= ++n)
798 break;
799 if (!p->pfik_tzero)
800 p->pfik_tzero = gettime();
801 memcpy(buf++, p, sizeof(*buf))__builtin_memcpy((buf++), (p), (sizeof(*buf)));
802 }
803 *size = n;
804}
805
806int
807pfi_skip_if(const char *filter, struct pfi_kif *p)
808{
809 struct ifg_list *i;
810 int n;
811
812 PF_ASSERT_LOCKED()do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail(
0x0001UL, rw_status(&pf_lock),__func__); } while (0)
;
813
814 if (filter == NULL((void *)0) || !*filter)
815 return (0);
816 if (!strcmp(p->pfik_name, filter))
817 return (0); /* exact match */
818 n = strlen(filter);
819 if (n < 1 || n >= IFNAMSIZ16)
820 return (1); /* sanity check */
821 if (filter[n-1] >= '0' && filter[n-1] <= '9')
822 return (1); /* group names may not end in a digit */
823 if (p->pfik_ifp != NULL((void *)0))
824 TAILQ_FOREACH(i, &p->pfik_ifp->if_groups, ifgl_next)for((i) = ((&p->pfik_ifp->if_groups)->tqh_first)
; (i) != ((void *)0); (i) = ((i)->ifgl_next.tqe_next))
825 if (!strncmp(i->ifgl_group->ifg_group, filter, IFNAMSIZ16))
826 return (0); /* iface is in group "filter" */
827 return (1);
828}
829
830int
831pfi_set_flags(const char *name, int flags)
832{
833 struct pfi_kif *p;
834 size_t n;
835
836 PF_ASSERT_LOCKED()do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail(
0x0001UL, rw_status(&pf_lock),__func__); } while (0)
;
837
838 if (name != NULL((void *)0) && name[0] != '\0') {
839 p = pfi_kif_find(name);
840 if (p == NULL((void *)0)) {
841 n = strlen(name);
842 if (n < 1 || n >= IFNAMSIZ16)
843 return (EINVAL22);
844
845 if (!isalpha(name[0])(((name[0]) >= 'A' && (name[0]) <= 'Z')||((name
[0]) >= 'a' && (name[0]) <= 'z'))
)
846 return (EINVAL22);
847
848 p = pfi_kif_get(name, NULL((void *)0));
849 if (p != NULL((void *)0)) {
850 p->pfik_flags_new = p->pfik_flags | flags;
851 /*
852 * We use pfik_flagrefs counter as an
853 * indication whether the kif has been created
854 * on behalf of 'pfi_set_flags()' or not.
855 */
856 KASSERT(p->pfik_flagrefs == 0)((p->pfik_flagrefs == 0) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/net/pf_if.c", 856, "p->pfik_flagrefs == 0"
))
;
857 if (ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP)((p->pfik_flags_new) & (0x0100)))
858 pfi_kif_ref(p, PFI_KIF_REF_FLAG);
859 } else
860 panic("%s pfi_kif_get() returned NULL\n",
861 __func__);
862 } else
863 p->pfik_flags_new = p->pfik_flags | flags;
864 } else {
865 RB_FOREACH(p, pfi_ifhead, &pfi_ifs)for ((p) = pfi_ifhead_RB_MINMAX(&pfi_ifs, -1); (p) != ((void
*)0); (p) = pfi_ifhead_RB_NEXT(p))
866 p->pfik_flags_new = p->pfik_flags | flags;
867 }
868
869 return (0);
870}
871
872int
873pfi_clear_flags(const char *name, int flags)
874{
875 struct pfi_kif *p, *w;
876
877 PF_ASSERT_LOCKED()do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail(
0x0001UL, rw_status(&pf_lock),__func__); } while (0)
;
878
879 if (name != NULL((void *)0) && name[0] != '\0') {
880 p = pfi_kif_find(name);
881 if (p != NULL((void *)0)) {
882 p->pfik_flags_new = p->pfik_flags & ~flags;
883
884 KASSERT((p->pfik_flagrefs == 0) ||(((p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 885, "(p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)"
))
885 (p->pfik_flagrefs == 1))(((p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 885, "(p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)"
))
;
886
887 if (!ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP)((p->pfik_flags_new) & (0x0100)) &&
888 (p->pfik_flagrefs == 1))
889 pfi_kif_unref(p, PFI_KIF_REF_FLAG);
890 } else
891 return (ESRCH3);
892
893 } else
894 RB_FOREACH_SAFE(p, pfi_ifhead, &pfi_ifs, w)for ((p) = pfi_ifhead_RB_MINMAX(&pfi_ifs, -1); ((p) != ((
void *)0)) && ((w) = pfi_ifhead_RB_NEXT(p), 1); (p) =
(w))
{
895 p->pfik_flags_new = p->pfik_flags & ~flags;
896
897 KASSERT((p->pfik_flagrefs == 0) ||(((p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 898, "(p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)"
))
898 (p->pfik_flagrefs == 1))(((p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 898, "(p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)"
))
;
899
900 if (!ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP)((p->pfik_flags_new) & (0x0100)) &&
901 (p->pfik_flagrefs == 1))
902 pfi_kif_unref(p, PFI_KIF_REF_FLAG);
903 }
904
905 return (0);
906}
907
908void
909pfi_xcommit(void)
910{
911 struct pfi_kif *p, *gkif;
912 struct ifg_list *g;
913 struct ifnet *ifp;
914 size_t n;
915
916 PF_ASSERT_LOCKED()do { if (rw_status(&pf_lock) != 0x0001UL) splassert_fail(
0x0001UL, rw_status(&pf_lock),__func__); } while (0)
;
917
918 RB_FOREACH(p, pfi_ifhead, &pfi_ifs)for ((p) = pfi_ifhead_RB_MINMAX(&pfi_ifs, -1); (p) != ((void
*)0); (p) = pfi_ifhead_RB_NEXT(p))
{
919 p->pfik_flags = p->pfik_flags_new;
920 n = strlen(p->pfik_name);
Value stored to 'n' is never read
921 ifp = p->pfik_ifp;
922 /*
923 * if kif is backed by existing interface, then we must use
924 * skip flags found in groups. We use pfik_flags_new, otherwise
925 * we would need to do two RB_FOREACH() passes: the first to
926 * commit group changes the second to commit flag changes for
927 * interfaces.
928 */
929 if (ifp != NULL((void *)0))
930 TAILQ_FOREACH(g, &ifp->if_groups, ifgl_next)for((g) = ((&ifp->if_groups)->tqh_first); (g) != ((
void *)0); (g) = ((g)->ifgl_next.tqe_next))
{
931 gkif =
932 (struct pfi_kif *)g->ifgl_group->ifg_pf_kif;
933 KASSERT(gkif != NULL)((gkif != ((void *)0)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 933, "gkif != NULL"))
;
934 p->pfik_flags |= gkif->pfik_flags_new;
935 }
936 }
937}
938
939/* from pf_print_state.c */
940int
941pfi_unmask(void *addr)
942{
943 struct pf_addr *m = addr;
944 int i = 31, j = 0, b = 0;
945 u_int32_t tmp;
946
947 while (j < 4 && m->addr32pfa.addr32[j] == 0xffffffff) {
948 b += 32;
949 j++;
950 }
951 if (j < 4) {
952 tmp = ntohl(m->addr32[j])(__uint32_t)(__builtin_constant_p(m->pfa.addr32[j]) ? (__uint32_t
)(((__uint32_t)(m->pfa.addr32[j]) & 0xff) << 24 |
((__uint32_t)(m->pfa.addr32[j]) & 0xff00) << 8 |
((__uint32_t)(m->pfa.addr32[j]) & 0xff0000) >> 8
| ((__uint32_t)(m->pfa.addr32[j]) & 0xff000000) >>
24) : __swap32md(m->pfa.addr32[j]))
;
953 for (i = 31; tmp & (1 << i); --i)
954 b++;
955 }
956 return (b);
957}
958