Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pf_if.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -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 -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/lib/clang/13.0.0 -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/swsmu -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/powerplay -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/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 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 -D CONFIG_DRM_AMD_DC_DCN3_0 -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 -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 /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/net/pf_if.c
1/* $OpenBSD: pf_if.c,v 1.103 2021/12/26 01:00:32 sashan 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#ifdef INET61
57#include <netinet/ip6.h>
58#endif /* INET6 */
59
60#define isupper(c)((c) >= 'A' && (c) <= 'Z') ((c) >= 'A' && (c) <= 'Z')
61#define islower(c)((c) >= 'a' && (c) <= 'z') ((c) >= 'a' && (c) <= 'z')
62#define isalpha(c)(((c) >= 'A' && (c) <= 'Z')||((c) >= 'a' &&
(c) <= 'z'))
(isupper(c)((c) >= 'A' && (c) <= 'Z')||islower(c)((c) >= 'a' && (c) <= 'z'))
63
64struct pfi_kif *pfi_all = NULL((void *)0);
65struct pool pfi_addr_pl;
66struct pfi_ifhead pfi_ifs;
67long pfi_update = 1;
68struct pfr_addr *pfi_buffer;
69int pfi_buffer_cnt;
70int pfi_buffer_max;
71
72void pfi_kif_update(struct pfi_kif *);
73void pfi_dynaddr_update(struct pfi_dynaddr *dyn);
74void pfi_table_update(struct pfr_ktable *, struct pfi_kif *,
75 u_int8_t, int);
76void pfi_kifaddr_update(void *);
77void pfi_instance_add(struct ifnet *, u_int8_t, int);
78void pfi_address_add(struct sockaddr *, sa_family_t, u_int8_t);
79int pfi_if_compare(struct pfi_kif *, struct pfi_kif *);
80int pfi_skip_if(const char *, struct pfi_kif *);
81int pfi_unmask(void *);
82void pfi_group_change(const char *);
83
84RB_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);
;
85RB_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); }
;
86
87#define PFI_BUFFER_MAX0x10000 0x10000
88#define PFI_MTYPE9 M_IFADDR9
89
90struct pfi_kif *
91pfi_kif_alloc(const char *kif_name, int mflags)
92{
93 struct pfi_kif *kif;
94
95 kif = malloc(sizeof(*pfi_all), PFI_MTYPE9, mflags|M_ZERO0x0008);
96 strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
97 kif->pfik_tzero = gettime();
98 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)
;
99
100 if (!strcmp(kif->pfik_name, "any")) {
101 /* both so it works in the ioctl and the regular case */
102 kif->pfik_flags |= PFI_IFLAG_ANY0x0200;
103 kif->pfik_flags_new |= PFI_IFLAG_ANY0x0200;
104 }
105
106 return (kif);
107}
108
109void
110pfi_kif_free(struct pfi_kif *kif)
111{
112 if (kif == NULL((void *)0))
113 return;
114
115 if (kif->pfik_rules || kif->pfik_states || kif->pfik_routes ||
116 kif->pfik_srcnodes || kif->pfik_flagrefs)
117 panic("kif is still alive");
118
119 free(kif, PFI_MTYPE9, sizeof(*kif));
120}
121
122void
123pfi_initialize(void)
124{
125 /*
126 * The first time we arrive here is during kernel boot,
127 * when if_attachsetup() for the first time. No locking
128 * is needed in this case, because it's granted there
129 * is a single thread, which sets pfi_all global var.
130 */
131 if (pfi_all != NULL((void *)0)) /* already initialized */
132 return;
133
134 pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, IPL_SOFTNET0x5, 0,
135 "pfiaddrpl", NULL((void *)0));
136 pfi_buffer_max = 64;
137 pfi_buffer = mallocarray(pfi_buffer_max, sizeof(*pfi_buffer),
138 PFI_MTYPE9, M_WAITOK0x0001);
139
140 pfi_all = pfi_kif_alloc(IFG_ALL"all", M_WAITOK0x0001);
141
142 if (RB_INSERT(pfi_ifhead, &pfi_ifs, pfi_all)pfi_ifhead_RB_INSERT(&pfi_ifs, pfi_all) != NULL((void *)0))
143 panic("IFG_ALL kif found already");
144}
145
146struct pfi_kif *
147pfi_kif_find(const char *kif_name)
148{
149 struct pfi_kif_cmp s;
150
151 memset(&s, 0, sizeof(s))__builtin_memset((&s), (0), (sizeof(s)));
152 strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name));
153 return (RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s)pfi_ifhead_RB_FIND(&pfi_ifs, (struct pfi_kif *)&s));
154}
155
156struct pfi_kif *
157pfi_kif_get(const char *kif_name, struct pfi_kif **prealloc)
158{
159 struct pfi_kif *kif;
160
161 if ((kif = pfi_kif_find(kif_name)))
162 return (kif);
163
164 /* create new one */
165 if ((prealloc == NULL((void *)0)) || (*prealloc == NULL((void *)0))) {
166 kif = pfi_kif_alloc(kif_name, M_NOWAIT0x0002);
167 if (kif == NULL((void *)0))
168 return (NULL((void *)0));
169 } else {
170 kif = *prealloc;
171 *prealloc = NULL((void *)0);
172 }
173
174 RB_INSERT(pfi_ifhead, &pfi_ifs, kif)pfi_ifhead_RB_INSERT(&pfi_ifs, kif);
175 return (kif);
176}
177
178void
179pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what)
180{
181 switch (what) {
182 case PFI_KIF_REF_RULE:
183 kif->pfik_rules++;
184 break;
185 case PFI_KIF_REF_STATE:
186 kif->pfik_states++;
187 break;
188 case PFI_KIF_REF_ROUTE:
189 kif->pfik_routes++;
190 break;
191 case PFI_KIF_REF_SRCNODE:
192 kif->pfik_srcnodes++;
193 break;
194 case PFI_KIF_REF_FLAG:
195 kif->pfik_flagrefs++;
196 break;
197 default:
198 panic("pfi_kif_ref with unknown type");
199 }
200}
201
202void
203pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what)
204{
205 if (kif == NULL((void *)0))
206 return;
207
208 switch (what) {
209 case PFI_KIF_REF_NONE:
210 break;
211 case PFI_KIF_REF_RULE:
212 if (kif->pfik_rules <= 0) {
213 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)
214 "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)
215 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)
;
216 return;
217 }
218 kif->pfik_rules--;
219 break;
220 case PFI_KIF_REF_STATE:
221 if (kif->pfik_states <= 0) {
222 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)
223 "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)
224 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)
;
225 return;
226 }
227 kif->pfik_states--;
228 break;
229 case PFI_KIF_REF_ROUTE:
230 if (kif->pfik_routes <= 0) {
231 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)
232 "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)
233 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)
;
234 return;
235 }
236 kif->pfik_routes--;
237 break;
238 case PFI_KIF_REF_SRCNODE:
239 if (kif->pfik_srcnodes <= 0) {
240 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)
241 "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)
242 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)
;
243 return;
244 }
245 kif->pfik_srcnodes--;
246 break;
247 case PFI_KIF_REF_FLAG:
248 if (kif->pfik_flagrefs <= 0) {
249 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)
250 "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)
251 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)
;
252 return;
253 }
254 kif->pfik_flagrefs--;
255 break;
256 default:
257 panic("pfi_kif_unref (%s) with unknown type", kif->pfik_name);
258 }
259
260 if (kif->pfik_ifp != NULL((void *)0) || kif->pfik_group != NULL((void *)0) || kif == pfi_all)
261 return;
262
263 if (kif->pfik_rules || kif->pfik_states || kif->pfik_routes ||
264 kif->pfik_srcnodes || kif->pfik_flagrefs)
265 return;
266
267 RB_REMOVE(pfi_ifhead, &pfi_ifs, kif)pfi_ifhead_RB_REMOVE(&pfi_ifs, kif);
268 free(kif, PFI_MTYPE9, sizeof(*kif));
269}
270
271int
272pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif)
273{
274 struct ifg_list *p;
275
276 if (rule_kif == NULL((void *)0) || rule_kif == packet_kif)
277 return (1);
278
279 if (rule_kif->pfik_group != NULL((void *)0))
280 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))
281 if (p->ifgl_group == rule_kif->pfik_group)
282 return (1);
283
284 if (rule_kif->pfik_flags & PFI_IFLAG_ANY0x0200 && packet_kif->pfik_ifp &&
285 !(packet_kif->pfik_ifp->if_flags & IFF_LOOPBACK0x8))
286 return (1);
287
288 return (0);
289}
290
291void
292pfi_attach_ifnet(struct ifnet *ifp)
293{
294 struct pfi_kif *kif;
295 struct task *t;
296
297 pfi_initialize();
298 pfi_update++;
299 if ((kif = pfi_kif_get(ifp->if_xname, NULL((void *)0))) == NULL((void *)0))
300 panic("%s: pfi_kif_get failed", __func__);
301
302 kif->pfik_ifp = ifp;
303 ifp->if_pf_kif = (caddr_t)kif;
304
305 t = malloc(sizeof(*t), PFI_MTYPE9, M_WAITOK0x0001);
306 task_set(t, pfi_kifaddr_update, kif);
307 if_addrhook_add(ifp, t);
308 kif->pfik_ah_cookie = t;
309
310 pfi_kif_update(kif);
311}
312
313void
314pfi_detach_ifnet(struct ifnet *ifp)
315{
316 struct pfi_kif *kif;
317 struct task *t;
318
319 if ((kif = (struct pfi_kif *)ifp->if_pf_kif) == NULL((void *)0))
320 return;
321
322 pfi_update++;
323 t = kif->pfik_ah_cookie;
324 kif->pfik_ah_cookie = NULL((void *)0);
325 if_addrhook_del(ifp, t);
326 free(t, PFI_MTYPE9, sizeof(*t));
327
328 pfi_kif_update(kif);
329
330 kif->pfik_ifp = NULL((void *)0);
331 ifp->if_pf_kif = NULL((void *)0);
332 pfi_kif_unref(kif, PFI_KIF_REF_NONE);
333}
334
335void
336pfi_attach_ifgroup(struct ifg_group *ifg)
337{
338 struct pfi_kif *kif;
339
340 pfi_initialize();
341 pfi_update++;
342 if ((kif = pfi_kif_get(ifg->ifg_group, NULL((void *)0))) == NULL((void *)0))
343 panic("%s: pfi_kif_get failed", __func__);
344
345 kif->pfik_group = ifg;
346 ifg->ifg_pf_kif = (caddr_t)kif;
347}
348
349void
350pfi_detach_ifgroup(struct ifg_group *ifg)
351{
352 struct pfi_kif *kif;
353
354 if ((kif = (struct pfi_kif *)ifg->ifg_pf_kif) == NULL((void *)0))
355 return;
356
357 pfi_update++;
358
359 kif->pfik_group = NULL((void *)0);
360 ifg->ifg_pf_kif = NULL((void *)0);
361 pfi_kif_unref(kif, PFI_KIF_REF_NONE);
362}
363
364void
365pfi_group_change(const char *group)
366{
367 struct pfi_kif *kif;
368
369 pfi_update++;
370 if ((kif = pfi_kif_get(group, NULL((void *)0))) == NULL((void *)0))
371 panic("%s: pfi_kif_get failed", __func__);
372
373 pfi_kif_update(kif);
374}
375
376void
377pfi_group_delmember(const char *group)
378{
379 pfi_group_change(group);
380 pfi_xcommit();
381}
382
383void
384pfi_group_addmember(const char *group)
385{
386 pfi_group_change(group);
387 pfi_xcommit();
388}
389
390int
391pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
392{
393 switch (af) {
394 case AF_INET2:
395 switch (dyn->pfid_acnt4) {
396 case 0:
397 return (0);
398 case 1:
399 return (pf_match_addr(0, &dyn->pfid_addr4,
400 &dyn->pfid_mask4, a, AF_INET2));
401 default:
402 return (pfr_match_addr(dyn->pfid_kt, a, AF_INET2));
403 }
404 break;
405#ifdef INET61
406 case AF_INET624:
407 switch (dyn->pfid_acnt6) {
408 case 0:
409 return (0);
410 case 1:
411 return (pf_match_addr(0, &dyn->pfid_addr6,
412 &dyn->pfid_mask6, a, AF_INET624));
413 default:
414 return (pfr_match_addr(dyn->pfid_kt, a, AF_INET624));
415 }
416 break;
417#endif /* INET6 */
418 default:
419 return (0);
420 }
421}
422
423int
424pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
425{
426 struct pfi_dynaddr *dyn;
427 char tblname[PF_TABLE_NAME_SIZE32];
428 struct pf_ruleset *ruleset = NULL((void *)0);
429 int rv = 0;
430
431 if (aw->type != PF_ADDR_DYNIFTL)
432 return (0);
433 if ((dyn = pool_get(&pfi_addr_pl, PR_WAITOK0x0001 | PR_LIMITFAIL0x0004 | PR_ZERO0x0008))
434 == NULL((void *)0))
435 return (1);
436
437 if (!strcmp(aw->v.ifname, "self"))
438 dyn->pfid_kif = pfi_kif_get(IFG_ALL"all", NULL((void *)0));
439 else
440 dyn->pfid_kif = pfi_kif_get(aw->v.ifname, NULL((void *)0));
441 if (dyn->pfid_kif == NULL((void *)0)) {
442 rv = 1;
443 goto _bad;
444 }
445 pfi_kif_ref(dyn->pfid_kif, PFI_KIF_REF_RULE);
446
447 dyn->pfid_net = pfi_unmask(&aw->v.a.mask);
448 if (af == AF_INET2 && dyn->pfid_net == 32)
449 dyn->pfid_net = 128;
450 strlcpy(tblname, aw->v.ifname, sizeof(tblname));
451 if (aw->iflags & PFI_AFLAG_NETWORK0x01)
452 strlcat(tblname, ":network", sizeof(tblname));
453 if (aw->iflags & PFI_AFLAG_BROADCAST0x02)
454 strlcat(tblname, ":broadcast", sizeof(tblname));
455 if (aw->iflags & PFI_AFLAG_PEER0x04)
456 strlcat(tblname, ":peer", sizeof(tblname));
457 if (aw->iflags & PFI_AFLAG_NOALIAS0x08)
458 strlcat(tblname, ":0", sizeof(tblname));
459 if (dyn->pfid_net != 128)
460 snprintf(tblname + strlen(tblname),
461 sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net);
462 if ((ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR"_pf")) == NULL((void *)0)) {
463 rv = 1;
464 goto _bad;
465 }
466
467 if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, 1)) == NULL((void *)0)) {
468 rv = 1;
469 goto _bad;
470 }
471
472 dyn->pfid_kt->pfrkt_flagspfrkt_ts.pfrts_t.pfrt_flags |= PFR_TFLAG_ACTIVE0x00000004;
473 dyn->pfid_iflags = aw->iflags;
474 dyn->pfid_af = af;
475
476 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)
;
477 aw->p.dyn = dyn;
478 pfi_kif_update(dyn->pfid_kif);
479 return (0);
480
481_bad:
482 if (dyn->pfid_kt != NULL((void *)0))
483 pfr_detach_table(dyn->pfid_kt);
484 if (ruleset != NULL((void *)0))
485 pf_remove_if_empty_ruleset(ruleset);
486 if (dyn->pfid_kif != NULL((void *)0))
487 pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE);
488 pool_put(&pfi_addr_pl, dyn);
489 return (rv);
490}
491
492void
493pfi_kif_update(struct pfi_kif *kif)
494{
495 struct ifg_list *ifgl;
496 struct pfi_dynaddr *p;
497
498 /* update all dynaddr */
499 TAILQ_FOREACH(p, &kif->pfik_dynaddrs, entry)for((p) = ((&kif->pfik_dynaddrs)->tqh_first); (p) !=
((void *)0); (p) = ((p)->entry.tqe_next))
500 pfi_dynaddr_update(p);
501
502 /* again for all groups kif is member of */
503 if (kif->pfik_ifp != NULL((void *)0))
504 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
))
505 pfi_kif_update((struct pfi_kif *)
506 ifgl->ifgl_group->ifg_pf_kif);
507}
508
509void
510pfi_dynaddr_update(struct pfi_dynaddr *dyn)
511{
512 struct pfi_kif *kif;
513 struct pfr_ktable *kt;
514
515 if (dyn == NULL((void *)0) || dyn->pfid_kif == NULL((void *)0) || dyn->pfid_kt == NULL((void *)0))
516 panic("pfi_dynaddr_update");
517
518 kif = dyn->pfid_kif;
519 kt = dyn->pfid_kt;
520
521 if (kt->pfrkt_larg != pfi_update) {
522 /* this table needs to be brought up-to-date */
523 pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags);
524 kt->pfrkt_larg = pfi_update;
525 }
526 pfr_dynaddr_update(kt, dyn);
527}
528
529void
530pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, u_int8_t net, int flags)
531{
532 int e, size2 = 0;
533 struct ifg_member *ifgm;
534
535 pfi_buffer_cnt = 0;
536
537 if (kif->pfik_ifp != NULL((void *)0))
538 pfi_instance_add(kif->pfik_ifp, net, flags);
539 else if (kif->pfik_group != NULL((void *)0))
540 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
))
541 pfi_instance_add(ifgm->ifgm_ifp, net, flags);
542
543 if ((e = pfr_set_addrs(&kt->pfrkt_tpfrkt_ts.pfrts_t, pfi_buffer, pfi_buffer_cnt, &size2,
544 NULL((void *)0), NULL((void *)0), NULL((void *)0), 0, PFR_TFLAG_ALLMASK0x0000007F)))
545 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)
546 "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)
547 "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)
;
548}
549
550void
551pfi_instance_add(struct ifnet *ifp, u_int8_t net, int flags)
552{
553 struct ifaddr *ifa;
554 int got4 = 0, got6 = 0;
555 int net2, af;
556
557 if (ifp == NULL((void *)0))
558 return;
559 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)for((ifa) = ((&ifp->if_addrlist)->tqh_first); (ifa)
!= ((void *)0); (ifa) = ((ifa)->ifa_list.tqe_next))
{
560 if (ifa->ifa_addr == NULL((void *)0))
561 continue;
562 af = ifa->ifa_addr->sa_family;
563 if (af != AF_INET2 && af != AF_INET624)
564 continue;
565 if ((flags & PFI_AFLAG_BROADCAST0x02) && af == AF_INET624)
566 continue;
567 if ((flags & PFI_AFLAG_BROADCAST0x02) &&
568 !(ifp->if_flags & IFF_BROADCAST0x2))
569 continue;
570 if ((flags & PFI_AFLAG_PEER0x04) &&
571 !(ifp->if_flags & IFF_POINTOPOINT0x10))
572 continue;
573 if ((flags & PFI_AFLAG_NETWORK0x01) && af == AF_INET624 &&
574 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))
575 &((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))
)
576 continue;
577 if (flags & PFI_AFLAG_NOALIAS0x08) {
578 if (af == AF_INET2 && got4)
579 continue;
580 if (af == AF_INET624 && got6)
581 continue;
582 }
583 if (af == AF_INET2)
584 got4 = 1;
585 else if (af == AF_INET624)
586 got6 = 1;
587 net2 = net;
588 if (net2 == 128 && (flags & PFI_AFLAG_NETWORK0x01)) {
589 if (af == AF_INET2)
590 net2 = pfi_unmask(&((struct sockaddr_in *)
591 ifa->ifa_netmask)->sin_addr);
592 else if (af == AF_INET624)
593 net2 = pfi_unmask(&((struct sockaddr_in6 *)
594 ifa->ifa_netmask)->sin6_addr);
595 }
596 if (af == AF_INET2 && net2 > 32)
597 net2 = 32;
598 if (flags & PFI_AFLAG_BROADCAST0x02)
599 pfi_address_add(ifa->ifa_broadaddrifa_dstaddr, af, net2);
600 else if (flags & PFI_AFLAG_PEER0x04)
601 pfi_address_add(ifa->ifa_dstaddr, af, net2);
602 else
603 pfi_address_add(ifa->ifa_addr, af, net2);
604 }
605}
606
607void
608pfi_address_add(struct sockaddr *sa, sa_family_t af, u_int8_t net)
609{
610 struct pfr_addr *p;
611 int i;
612
613 if (pfi_buffer_cnt >= pfi_buffer_max) {
614 int new_max = pfi_buffer_max * 2;
615
616 if (new_max > PFI_BUFFER_MAX0x10000) {
617 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)
618 "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)
619 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)
;
620 return;
621 }
622 p = mallocarray(new_max, sizeof(*pfi_buffer), PFI_MTYPE9,
623 M_DONTWAIT0x0002);
624 if (p == NULL((void *)0)) {
625 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)
626 "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)
627 "(%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)
;
628 return;
629 }
630 memcpy(p, pfi_buffer, pfi_buffer_max * sizeof(*pfi_buffer))__builtin_memcpy((p), (pfi_buffer), (pfi_buffer_max * sizeof(
*pfi_buffer)))
;
631 /* no need to zero buffer */
632 free(pfi_buffer, PFI_MTYPE9, pfi_buffer_max * sizeof(*pfi_buffer));
633 pfi_buffer = p;
634 pfi_buffer_max = new_max;
635 }
636 if (af == AF_INET2 && net > 32)
637 net = 128;
638 p = pfi_buffer + pfi_buffer_cnt++;
639 memset(p, 0, sizeof(*p))__builtin_memset((p), (0), (sizeof(*p)));
640 p->pfra_af = af;
641 p->pfra_net = net;
642 if (af == AF_INET2)
643 p->pfra_ip4addrpfra_u._pfra_ip4addr = ((struct sockaddr_in *)sa)->sin_addr;
644 else if (af == AF_INET624) {
645 p->pfra_ip6addrpfra_u._pfra_ip6addr = ((struct sockaddr_in6 *)sa)->sin6_addr;
646 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))))
)
647 p->pfra_ip6addrpfra_u._pfra_ip6addr.s6_addr16__u6_addr.__u6_addr16[1] = 0;
648 }
649 /* mask network address bits */
650 if (net < 128)
651 ((caddr_t)p)[p->pfra_net/8] &= ~(0xFF >> (p->pfra_net%8));
652 for (i = (p->pfra_net+7)/8; i < sizeof(p->pfra_u); i++)
653 ((caddr_t)p)[i] = 0;
654}
655
656void
657pfi_dynaddr_remove(struct pf_addr_wrap *aw)
658{
659 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL((void *)0) ||
660 aw->p.dyn->pfid_kif == NULL((void *)0) || aw->p.dyn->pfid_kt == NULL((void *)0))
661 return;
662
663 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)
;
664 pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE);
665 aw->p.dyn->pfid_kif = NULL((void *)0);
666 pfr_detach_table(aw->p.dyn->pfid_kt);
667 aw->p.dyn->pfid_kt = NULL((void *)0);
668 pool_put(&pfi_addr_pl, aw->p.dyn);
669 aw->p.dyn = NULL((void *)0);
670}
671
672void
673pfi_dynaddr_copyout(struct pf_addr_wrap *aw)
674{
675 if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL((void *)0) ||
676 aw->p.dyn->pfid_kif == NULL((void *)0))
677 return;
678 aw->p.dyncnt = aw->p.dyn->pfid_acnt4 + aw->p.dyn->pfid_acnt6;
679}
680
681void
682pfi_kifaddr_update(void *v)
683{
684 struct pfi_kif *kif = (struct pfi_kif *)v;
685
686 NET_ASSERT_LOCKED()do { int _s = rw_status(&netlock); if ((splassert_ctl >
0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail
(0x0002UL, _s, __func__); } while (0)
;
687
688 pfi_update++;
689 pfi_kif_update(kif);
690}
691
692int
693pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
694{
695 return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ16));
696}
697
698void
699pfi_update_status(const char *name, struct pf_status *pfs)
700{
701 struct pfi_kif *p;
702 struct pfi_kif_cmp key;
703 struct ifg_member p_member, *ifgm;
704 TAILQ_HEAD(, ifg_member)struct { struct ifg_member *tqh_first; struct ifg_member **tqh_last
; }
ifg_members;
705 int i, j, k;
706
707 if (*name == '\0' && pfs == NULL((void *)0)) {
708 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))
{
709 memset(p->pfik_packets, 0, sizeof(p->pfik_packets))__builtin_memset((p->pfik_packets), (0), (sizeof(p->pfik_packets
)))
;
710 memset(p->pfik_bytes, 0, sizeof(p->pfik_bytes))__builtin_memset((p->pfik_bytes), (0), (sizeof(p->pfik_bytes
)))
;
711 p->pfik_tzero = gettime();
712 }
713 return;
714 }
715
716 strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
717 p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key)pfi_ifhead_RB_FIND(&pfi_ifs, (struct pfi_kif *)&key);
718 if (p == NULL((void *)0)) {
719 return;
720 }
721 if (p->pfik_group != NULL((void *)0)) {
722 memcpy(&ifg_members, &p->pfik_group->ifg_members,__builtin_memcpy((&ifg_members), (&p->pfik_group->
ifg_members), (sizeof(ifg_members)))
723 sizeof(ifg_members))__builtin_memcpy((&ifg_members), (&p->pfik_group->
ifg_members), (sizeof(ifg_members)))
;
724 } else {
725 /* build a temporary list for p only */
726 memset(&p_member, 0, sizeof(p_member))__builtin_memset((&p_member), (0), (sizeof(p_member)));
727 p_member.ifgm_ifp = p->pfik_ifp;
728 TAILQ_INIT(&ifg_members)do { (&ifg_members)->tqh_first = ((void *)0); (&ifg_members
)->tqh_last = &(&ifg_members)->tqh_first; } while
(0)
;
729 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)
;
730 }
731 if (pfs) {
732 memset(pfs->pcounters, 0, sizeof(pfs->pcounters))__builtin_memset((pfs->pcounters), (0), (sizeof(pfs->pcounters
)))
;
733 memset(pfs->bcounters, 0, sizeof(pfs->bcounters))__builtin_memset((pfs->bcounters), (0), (sizeof(pfs->bcounters
)))
;
734 }
735 TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next)for((ifgm) = ((&ifg_members)->tqh_first); (ifgm) != ((
void *)0); (ifgm) = ((ifgm)->ifgm_next.tqe_next))
{
736 if (ifgm->ifgm_ifp == NULL((void *)0))
737 continue;
738 p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
739
740 /* just clear statistics */
741 if (pfs == NULL((void *)0)) {
742 memset(p->pfik_packets, 0, sizeof(p->pfik_packets))__builtin_memset((p->pfik_packets), (0), (sizeof(p->pfik_packets
)))
;
743 memset(p->pfik_bytes, 0, sizeof(p->pfik_bytes))__builtin_memset((p->pfik_bytes), (0), (sizeof(p->pfik_bytes
)))
;
744 p->pfik_tzero = gettime();
745 continue;
746 }
747 for (i = 0; i < 2; i++)
748 for (j = 0; j < 2; j++)
749 for (k = 0; k < 2; k++) {
750 pfs->pcounters[i][j][k] +=
751 p->pfik_packets[i][j][k];
752 pfs->bcounters[i][j] +=
753 p->pfik_bytes[i][j][k];
754 }
755 }
756}
757
758int
759pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
760{
761 struct pfi_kif *p, *nextp;
762 int n = 0;
763
764 for (p = RB_MIN(pfi_ifhead, &pfi_ifs)pfi_ifhead_RB_MINMAX(&pfi_ifs, -1); p; p = nextp) {
765 nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p)pfi_ifhead_RB_NEXT(p);
766 if (pfi_skip_if(name, p))
767 continue;
768 if (*size > n++) {
769 if (!p->pfik_tzero)
770 p->pfik_tzero = gettime();
771 pfi_kif_ref(p, PFI_KIF_REF_RULE);
772 if (copyout(p, buf++, sizeof(*buf))) {
773 pfi_kif_unref(p, PFI_KIF_REF_RULE);
774 return (EFAULT14);
775 }
776 nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p)pfi_ifhead_RB_NEXT(p);
777 pfi_kif_unref(p, PFI_KIF_REF_RULE);
778 }
779 }
780 *size = n;
781 return (0);
782}
783
784int
785pfi_skip_if(const char *filter, struct pfi_kif *p)
786{
787 struct ifg_list *i;
788 int n;
789
790 if (filter == NULL((void *)0) || !*filter)
791 return (0);
792 if (!strcmp(p->pfik_name, filter))
793 return (0); /* exact match */
794 n = strlen(filter);
795 if (n < 1 || n >= IFNAMSIZ16)
796 return (1); /* sanity check */
797 if (filter[n-1] >= '0' && filter[n-1] <= '9')
798 return (1); /* group names may not end in a digit */
799 if (p->pfik_ifp != NULL((void *)0))
800 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))
801 if (!strncmp(i->ifgl_group->ifg_group, filter, IFNAMSIZ16))
802 return (0); /* iface is in group "filter" */
803 return (1);
804}
805
806int
807pfi_set_flags(const char *name, int flags)
808{
809 struct pfi_kif *p;
810 size_t n;
811
812 if (name != NULL((void *)0) && name[0] != '\0') {
813 p = pfi_kif_find(name);
814 if (p == NULL((void *)0)) {
815 n = strlen(name);
816 if (n < 1 || n >= IFNAMSIZ16)
817 return (EINVAL22);
818
819 if (!isalpha(name[0])(((name[0]) >= 'A' && (name[0]) <= 'Z')||((name
[0]) >= 'a' && (name[0]) <= 'z'))
)
820 return (EINVAL22);
821
822 p = pfi_kif_get(name, NULL((void *)0));
823 if (p != NULL((void *)0)) {
824 p->pfik_flags_new = p->pfik_flags | flags;
825 /*
826 * We use pfik_flagrefs counter as an
827 * indication whether the kif has been created
828 * on behalf of 'pfi_set_flags()' or not.
829 */
830 KASSERT(p->pfik_flagrefs == 0)((p->pfik_flagrefs == 0) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/net/pf_if.c", 830, "p->pfik_flagrefs == 0"
))
;
831 if (ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP)((p->pfik_flags_new) & (0x0100)))
832 pfi_kif_ref(p, PFI_KIF_REF_FLAG);
833 } else
834 panic("%s pfi_kif_get() returned NULL\n",
835 __func__);
836 } else
837 p->pfik_flags_new = p->pfik_flags | flags;
838 } else {
839 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))
840 p->pfik_flags_new = p->pfik_flags | flags;
841 }
842
843 return (0);
844}
845
846int
847pfi_clear_flags(const char *name, int flags)
848{
849 struct pfi_kif *p, *w;
850
851 if (name != NULL((void *)0) && name[0] != '\0') {
852 p = pfi_kif_find(name);
853 if (p != NULL((void *)0)) {
854 p->pfik_flags_new = p->pfik_flags & ~flags;
855
856 KASSERT((p->pfik_flagrefs == 0) ||(((p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 857, "(p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)"
))
857 (p->pfik_flagrefs == 1))(((p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 857, "(p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)"
))
;
858
859 if (!ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP)((p->pfik_flags_new) & (0x0100)) &&
860 (p->pfik_flagrefs == 1))
861 pfi_kif_unref(p, PFI_KIF_REF_FLAG);
862 } else
863 return (ESRCH3);
864
865 } else
866 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))
{
867 p->pfik_flags_new = p->pfik_flags & ~flags;
868
869 KASSERT((p->pfik_flagrefs == 0) ||(((p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 870, "(p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)"
))
870 (p->pfik_flagrefs == 1))(((p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 870, "(p->pfik_flagrefs == 0) || (p->pfik_flagrefs == 1)"
))
;
871
872 if (!ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP)((p->pfik_flags_new) & (0x0100)) &&
873 (p->pfik_flagrefs == 1))
874 pfi_kif_unref(p, PFI_KIF_REF_FLAG);
875 }
876
877 return (0);
878}
879
880void
881pfi_xcommit(void)
882{
883 struct pfi_kif *p, *gkif;
884 struct ifg_list *g;
885 struct ifnet *ifp;
886 size_t n;
887
888 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))
{
889 p->pfik_flags = p->pfik_flags_new;
890 n = strlen(p->pfik_name);
Value stored to 'n' is never read
891 ifp = p->pfik_ifp;
892 /*
893 * if kif is backed by existing interface, then we must use
894 * skip flags found in groups. We use pfik_flags_new, otherwise
895 * we would need to do two RB_FOREACH() passes: the first to
896 * commit group changes the second to commit flag changes for
897 * interfaces.
898 */
899 if (ifp != NULL((void *)0))
900 TAILQ_FOREACH(g, &ifp->if_groups, ifgl_next)for((g) = ((&ifp->if_groups)->tqh_first); (g) != ((
void *)0); (g) = ((g)->ifgl_next.tqe_next))
{
901 gkif =
902 (struct pfi_kif *)g->ifgl_group->ifg_pf_kif;
903 KASSERT(gkif != NULL)((gkif != ((void *)0)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/net/pf_if.c"
, 903, "gkif != NULL"))
;
904 p->pfik_flags |= gkif->pfik_flags_new;
905 }
906 }
907}
908
909/* from pf_print_state.c */
910int
911pfi_unmask(void *addr)
912{
913 struct pf_addr *m = addr;
914 int i = 31, j = 0, b = 0;
915 u_int32_t tmp;
916
917 while (j < 4 && m->addr32pfa.addr32[j] == 0xffffffff) {
918 b += 32;
919 j++;
920 }
921 if (j < 4) {
922 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]))
;
923 for (i = 31; tmp & (1 << i); --i)
924 b++;
925 }
926 return (b);
927}
928