]>
git.saurik.com Git - apple/xnu.git/blob - bsd/net/pf_if.c
2 * Copyright (c) 2007-2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* $apfw: pf_if.c,v 1.4 2008/08/27 00:01:32 jhw Exp $ */
30 /* $OpenBSD: pf_if.c,v 1.46 2006/12/13 09:01:59 itojun Exp $ */
33 * Copyright 2005 Henning Brauer <henning@openbsd.org>
34 * Copyright 2005 Ryan McBride <mcbride@openbsd.org>
35 * Copyright (c) 2001 Daniel Hartmeier
36 * Copyright (c) 2003 Cedric Berger
37 * All rights reserved.
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
43 * - Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * - Redistributions in binary form must reproduce the above
46 * copyright notice, this list of conditions and the following
47 * disclaimer in the documentation and/or other materials provided
48 * with the distribution.
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
53 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
54 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
55 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
56 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
58 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
60 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61 * POSSIBILITY OF SUCH DAMAGE.
64 #include <sys/param.h>
65 #include <sys/systm.h>
67 #include <sys/filio.h>
68 #include <sys/socket.h>
69 #include <sys/socketvar.h>
70 #include <sys/kernel.h>
72 #include <sys/malloc.h>
75 #include <net/if_types.h>
76 #include <net/if_var.h>
78 #include <netinet/in.h>
79 #include <netinet/in_var.h>
80 #include <netinet/in_systm.h>
81 #include <netinet/ip.h>
82 #include <netinet/ip_var.h>
84 #include <netinet/ip6.h>
86 #include <net/pfvar.h>
88 struct pfi_kif
*pfi_all
= NULL
;
90 static struct pool pfi_addr_pl
;
91 static struct pfi_ifhead pfi_ifs
;
92 static u_int32_t pfi_update
= 1;
93 static struct pfr_addr
*pfi_buffer
;
94 static int pfi_buffer_cnt
;
95 static int pfi_buffer_max
;
97 __private_extern__
void pfi_kifaddr_update(void *);
99 static void pfi_kif_update(struct pfi_kif
*);
100 static void pfi_dynaddr_update(struct pfi_dynaddr
*dyn
);
101 static void pfi_table_update(struct pfr_ktable
*, struct pfi_kif
*, uint8_t, int);
102 static void pfi_instance_add(struct ifnet
*, uint8_t, int);
103 static void pfi_address_add(struct sockaddr
*, uint8_t, uint8_t);
104 static int pfi_if_compare(struct pfi_kif
*, struct pfi_kif
*);
105 static int pfi_skip_if(const char *, struct pfi_kif
*);
106 static uint8_t pfi_unmask(void *);
108 RB_PROTOTYPE_SC(static, pfi_ifhead
, pfi_kif
, pfik_tree
, pfi_if_compare
);
109 RB_GENERATE(pfi_ifhead
, pfi_kif
, pfik_tree
, pfi_if_compare
);
111 #define PFI_BUFFER_MAX 0x10000
112 #define PFI_MTYPE M_IFADDR
114 #define IFG_ALL "ALL"
119 if (pfi_all
!= NULL
) { /* already initialized */
123 pool_init(&pfi_addr_pl
, sizeof(struct pfi_dynaddr
), 0, 0, 0,
126 pfi_buffer
= _MALLOC(pfi_buffer_max
* sizeof(*pfi_buffer
),
127 PFI_MTYPE
, M_WAITOK
);
129 if ((pfi_all
= pfi_kif_get(IFG_ALL
)) == NULL
) {
130 panic("pfi_kif_get for pfi_all failed");
138 pool_destroy(&pfi_addr_pl
);
139 _FREE(pfi_buffer
, PFI_MTYPE
);
144 pfi_kif_get(const char *kif_name
)
149 bzero(&s
.pfik_name
, sizeof(s
.pfik_name
));
150 strlcpy(s
.pfik_name
, kif_name
, sizeof(s
.pfik_name
));
151 kif
= RB_FIND(pfi_ifhead
, &pfi_ifs
, &s
);
157 if ((kif
= _MALLOC(sizeof(*kif
), PFI_MTYPE
, M_WAITOK
| M_ZERO
)) == NULL
) {
161 strlcpy(kif
->pfik_name
, kif_name
, sizeof(kif
->pfik_name
));
162 kif
->pfik_tzero
= pf_calendar_time_second();
163 TAILQ_INIT(&kif
->pfik_dynaddrs
);
165 RB_INSERT(pfi_ifhead
, &pfi_ifs
, kif
);
170 pfi_kif_ref(struct pfi_kif
*kif
, enum pfi_kif_refs what
)
173 case PFI_KIF_REF_RULE
:
176 case PFI_KIF_REF_STATE
:
180 panic("pfi_kif_ref with unknown type");
185 pfi_kif_unref(struct pfi_kif
*kif
, enum pfi_kif_refs what
)
192 case PFI_KIF_REF_NONE
:
194 case PFI_KIF_REF_RULE
:
195 if (kif
->pfik_rules
<= 0) {
196 printf("pfi_kif_unref: rules refcount <= 0\n");
201 case PFI_KIF_REF_STATE
:
202 if (kif
->pfik_states
<= 0) {
203 printf("pfi_kif_unref: state refcount <= 0\n");
209 panic("pfi_kif_unref with unknown type");
212 if (kif
->pfik_ifp
!= NULL
|| kif
== pfi_all
) {
216 if (kif
->pfik_rules
|| kif
->pfik_states
) {
220 RB_REMOVE(pfi_ifhead
, &pfi_ifs
, kif
);
221 _FREE(kif
, PFI_MTYPE
);
225 pfi_kif_match(struct pfi_kif
*rule_kif
, struct pfi_kif
*packet_kif
)
227 if (rule_kif
== NULL
|| rule_kif
== packet_kif
) {
235 pfi_attach_ifnet(struct ifnet
*ifp
)
239 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
242 if ((kif
= pfi_kif_get(if_name(ifp
))) == NULL
) {
243 panic("pfi_kif_get failed");
246 ifnet_lock_exclusive(ifp
);
248 ifp
->if_pf_kif
= kif
;
249 ifnet_lock_done(ifp
);
255 * Caller holds ifnet lock as writer (exclusive);
258 pfi_detach_ifnet(struct ifnet
*ifp
)
262 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
264 if ((kif
= (struct pfi_kif
*)ifp
->if_pf_kif
) == NULL
) {
271 ifnet_lock_exclusive(ifp
);
272 kif
->pfik_ifp
= NULL
;
273 ifp
->if_pf_kif
= NULL
;
274 ifnet_lock_done(ifp
);
276 pfi_kif_unref(kif
, PFI_KIF_REF_NONE
);
280 pfi_match_addr(struct pfi_dynaddr
*dyn
, struct pf_addr
*a
, sa_family_t af
)
285 switch (dyn
->pfid_acnt4
) {
289 return PF_MATCHA(0, &dyn
->pfid_addr4
,
290 &dyn
->pfid_mask4
, a
, AF_INET
);
292 return pfr_match_addr(dyn
->pfid_kt
, a
, AF_INET
);
296 switch (dyn
->pfid_acnt6
) {
300 return PF_MATCHA(0, &dyn
->pfid_addr6
,
301 &dyn
->pfid_mask6
, a
, AF_INET6
);
303 return pfr_match_addr(dyn
->pfid_kt
, a
, AF_INET6
);
311 pfi_dynaddr_setup(struct pf_addr_wrap
*aw
, sa_family_t af
)
313 struct pfi_dynaddr
*dyn
;
314 char tblname
[PF_TABLE_NAME_SIZE
];
315 struct pf_ruleset
*ruleset
= NULL
;
318 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
320 if (aw
->type
!= PF_ADDR_DYNIFTL
) {
323 if ((dyn
= pool_get(&pfi_addr_pl
, PR_WAITOK
)) == NULL
) {
326 bzero(dyn
, sizeof(*dyn
));
328 if (strcmp(aw
->v
.ifname
, "self") == 0) {
329 dyn
->pfid_kif
= pfi_kif_get(IFG_ALL
);
331 dyn
->pfid_kif
= pfi_kif_get(aw
->v
.ifname
);
333 if (dyn
->pfid_kif
== NULL
) {
337 pfi_kif_ref(dyn
->pfid_kif
, PFI_KIF_REF_RULE
);
339 dyn
->pfid_net
= pfi_unmask(&aw
->v
.a
.mask
);
340 if (af
== AF_INET
&& dyn
->pfid_net
== 32) {
343 strlcpy(tblname
, aw
->v
.ifname
, sizeof(tblname
));
344 if (aw
->iflags
& PFI_AFLAG_NETWORK
) {
345 strlcat(tblname
, ":network", sizeof(tblname
));
347 if (aw
->iflags
& PFI_AFLAG_BROADCAST
) {
348 strlcat(tblname
, ":broadcast", sizeof(tblname
));
350 if (aw
->iflags
& PFI_AFLAG_PEER
) {
351 strlcat(tblname
, ":peer", sizeof(tblname
));
353 if (aw
->iflags
& PFI_AFLAG_NOALIAS
) {
354 strlcat(tblname
, ":0", sizeof(tblname
));
356 if (dyn
->pfid_net
!= 128) {
357 snprintf(tblname
+ strlen(tblname
),
358 sizeof(tblname
) - strlen(tblname
), "/%d", dyn
->pfid_net
);
360 if ((ruleset
= pf_find_or_create_ruleset(PF_RESERVED_ANCHOR
)) == NULL
) {
365 if ((dyn
->pfid_kt
= pfr_attach_table(ruleset
, tblname
)) == NULL
) {
370 dyn
->pfid_kt
->pfrkt_flags
|= PFR_TFLAG_ACTIVE
;
371 dyn
->pfid_iflags
= aw
->iflags
;
374 TAILQ_INSERT_TAIL(&dyn
->pfid_kif
->pfik_dynaddrs
, dyn
, entry
);
376 pfi_kif_update(dyn
->pfid_kif
);
380 if (dyn
->pfid_kt
!= NULL
) {
381 pfr_detach_table(dyn
->pfid_kt
);
383 if (ruleset
!= NULL
) {
384 pf_remove_if_empty_ruleset(ruleset
);
386 if (dyn
->pfid_kif
!= NULL
) {
387 pfi_kif_unref(dyn
->pfid_kif
, PFI_KIF_REF_RULE
);
389 pool_put(&pfi_addr_pl
, dyn
);
394 pfi_kif_update(struct pfi_kif
*kif
)
396 struct pfi_dynaddr
*p
;
398 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
400 /* update all dynaddr */
401 TAILQ_FOREACH(p
, &kif
->pfik_dynaddrs
, entry
)
402 pfi_dynaddr_update(p
);
406 pfi_dynaddr_update(struct pfi_dynaddr
*dyn
)
409 struct pfr_ktable
*kt
;
411 if (dyn
== NULL
|| dyn
->pfid_kif
== NULL
|| dyn
->pfid_kt
== NULL
) {
412 panic("pfi_dynaddr_update");
418 if (kt
->pfrkt_larg
!= pfi_update
) {
419 /* this table needs to be brought up-to-date */
420 pfi_table_update(kt
, kif
, dyn
->pfid_net
, dyn
->pfid_iflags
);
421 kt
->pfrkt_larg
= pfi_update
;
423 pfr_dynaddr_update(kt
, dyn
);
427 pfi_table_update(struct pfr_ktable
*kt
, struct pfi_kif
*kif
, uint8_t net
, int flags
)
433 if (kif
->pfik_ifp
!= NULL
) {
434 pfi_instance_add(kif
->pfik_ifp
, net
, flags
);
437 if ((e
= pfr_set_addrs(&kt
->pfrkt_t
, CAST_USER_ADDR_T(pfi_buffer
),
438 pfi_buffer_cnt
, &size2
, NULL
, NULL
, NULL
, 0, PFR_TFLAG_ALLMASK
))) {
439 printf("pfi_table_update: cannot set %d new addresses "
440 "into table %s: %d\n", pfi_buffer_cnt
, kt
->pfrkt_name
, e
);
445 pfi_instance_add(struct ifnet
*ifp
, uint8_t net
, int flags
)
448 int got4
= 0, got6
= 0;
454 ifnet_lock_shared(ifp
);
455 TAILQ_FOREACH(ia
, &ifp
->if_addrhead
, ifa_link
) {
457 if (ia
->ifa_addr
== NULL
) {
461 af
= ia
->ifa_addr
->sa_family
;
462 if (af
!= AF_INET
&& af
!= AF_INET6
) {
466 if ((flags
& PFI_AFLAG_BROADCAST
) && af
== AF_INET6
) {
470 if ((flags
& PFI_AFLAG_BROADCAST
) &&
471 !(ifp
->if_flags
& IFF_BROADCAST
)) {
475 if ((flags
& PFI_AFLAG_PEER
) &&
476 !(ifp
->if_flags
& IFF_POINTOPOINT
)) {
480 if ((af
== AF_INET6
) &&
481 IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6
*)
482 (void *)ia
->ifa_addr
)->sin6_addr
)) {
486 if ((af
== AF_INET6
) &&
487 (((struct in6_ifaddr
*)ia
)->ia6_flags
&
488 (IN6_IFF_ANYCAST
| IN6_IFF_NOTREADY
| IN6_IFF_DETACHED
|
489 IN6_IFF_CLAT46
| IN6_IFF_TEMPORARY
| IN6_IFF_DEPRECATED
))) {
493 if (flags
& PFI_AFLAG_NOALIAS
) {
494 if (af
== AF_INET
&& got4
) {
498 if (af
== AF_INET6
&& got6
) {
505 } else if (af
== AF_INET6
) {
509 if (net2
== 128 && (flags
& PFI_AFLAG_NETWORK
)) {
511 net2
= pfi_unmask(&((struct sockaddr_in
*)
512 (void *)ia
->ifa_netmask
)->sin_addr
);
513 } else if (af
== AF_INET6
) {
514 net2
= pfi_unmask(&((struct sockaddr_in6
*)
515 (void *)ia
->ifa_netmask
)->sin6_addr
);
518 if (af
== AF_INET
&& net2
> 32) {
521 if (flags
& PFI_AFLAG_BROADCAST
) {
522 pfi_address_add(ia
->ifa_broadaddr
, af
, net2
);
523 } else if (flags
& PFI_AFLAG_PEER
) {
524 pfi_address_add(ia
->ifa_dstaddr
, af
, net2
);
526 pfi_address_add(ia
->ifa_addr
, af
, net2
);
530 ifnet_lock_done(ifp
);
534 pfi_address_add(struct sockaddr
*sa
, uint8_t af
, uint8_t net
)
539 if (pfi_buffer_cnt
>= pfi_buffer_max
) {
540 int new_max
= pfi_buffer_max
* 2;
542 if (new_max
> PFI_BUFFER_MAX
) {
543 printf("pfi_address_add: address buffer full (%d/%d)\n",
544 pfi_buffer_cnt
, PFI_BUFFER_MAX
);
547 p
= _MALLOC(new_max
* sizeof(*pfi_buffer
), PFI_MTYPE
,
550 printf("pfi_address_add: no memory to grow buffer "
551 "(%d/%d)\n", pfi_buffer_cnt
, PFI_BUFFER_MAX
);
554 memcpy(p
, pfi_buffer
, pfi_buffer_max
* sizeof(*pfi_buffer
));
555 /* no need to zero buffer */
556 _FREE(pfi_buffer
, PFI_MTYPE
);
558 pfi_buffer_max
= new_max
;
560 if (af
== AF_INET
&& net
> 32) {
563 p
= pfi_buffer
+ pfi_buffer_cnt
++;
564 bzero(p
, sizeof(*p
));
568 p
->pfra_ip4addr
= ((struct sockaddr_in
*)(void *)sa
)->sin_addr
;
569 } else if (af
== AF_INET6
) {
571 ((struct sockaddr_in6
*)(void *)sa
)->sin6_addr
;
572 if (IN6_IS_SCOPE_EMBED(&p
->pfra_ip6addr
)) {
573 p
->pfra_ip6addr
.s6_addr16
[1] = 0;
576 /* mask network address bits */
578 ((caddr_t
)p
)[p
->pfra_net
/ 8] &= ~(0xFF >> (p
->pfra_net
% 8));
580 for (i
= (p
->pfra_net
+ 7) / 8; i
< (int)sizeof(p
->pfra_u
); i
++) {
586 pfi_dynaddr_remove(struct pf_addr_wrap
*aw
)
588 if (aw
->type
!= PF_ADDR_DYNIFTL
|| aw
->p
.dyn
== NULL
||
589 aw
->p
.dyn
->pfid_kif
== NULL
|| aw
->p
.dyn
->pfid_kt
== NULL
) {
593 TAILQ_REMOVE(&aw
->p
.dyn
->pfid_kif
->pfik_dynaddrs
, aw
->p
.dyn
, entry
);
594 pfi_kif_unref(aw
->p
.dyn
->pfid_kif
, PFI_KIF_REF_RULE
);
595 aw
->p
.dyn
->pfid_kif
= NULL
;
596 pfr_detach_table(aw
->p
.dyn
->pfid_kt
);
597 aw
->p
.dyn
->pfid_kt
= NULL
;
598 pool_put(&pfi_addr_pl
, aw
->p
.dyn
);
603 pfi_dynaddr_copyout(struct pf_addr_wrap
*aw
)
605 if (aw
->type
!= PF_ADDR_DYNIFTL
|| aw
->p
.dyn
== NULL
||
606 aw
->p
.dyn
->pfid_kif
== NULL
) {
609 aw
->p
.dyncnt
= aw
->p
.dyn
->pfid_acnt4
+ aw
->p
.dyn
->pfid_acnt6
;
613 pfi_kifaddr_update(void *v
)
615 struct pfi_kif
*kif
= (struct pfi_kif
*)v
;
617 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
624 pfi_if_compare(struct pfi_kif
*p
, struct pfi_kif
*q
)
626 return strncmp(p
->pfik_name
, q
->pfik_name
, IFNAMSIZ
- 1);
630 pfi_update_status(const char *name
, struct pf_status
*pfs
)
636 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
638 bzero(&key
.pfik_name
, sizeof(key
.pfik_name
));
639 strlcpy(key
.pfik_name
, name
, sizeof(key
.pfik_name
));
640 p
= RB_FIND(pfi_ifhead
, &pfi_ifs
, &key
);
646 bzero(pfs
->pcounters
, sizeof(pfs
->pcounters
));
647 bzero(pfs
->bcounters
, sizeof(pfs
->bcounters
));
648 for (i
= 0; i
< 2; i
++) {
649 for (j
= 0; j
< 2; j
++) {
650 for (k
= 0; k
< 2; k
++) {
651 pfs
->pcounters
[i
][j
][k
] +=
652 p
->pfik_packets
[i
][j
][k
];
653 pfs
->bcounters
[i
][j
] +=
654 p
->pfik_bytes
[i
][j
][k
];
659 /* just clear statistics */
660 bzero(p
->pfik_packets
, sizeof(p
->pfik_packets
));
661 bzero(p
->pfik_bytes
, sizeof(p
->pfik_bytes
));
662 p
->pfik_tzero
= pf_calendar_time_second();
667 pfi_get_ifaces(const char *name
, user_addr_t buf
, int *size
)
669 struct pfi_kif
*p
, *nextp
;
672 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
674 for (p
= RB_MIN(pfi_ifhead
, &pfi_ifs
); p
; p
= nextp
) {
675 nextp
= RB_NEXT(pfi_ifhead
, &pfi_ifs
, p
);
676 if (pfi_skip_if(name
, p
)) {
682 if (!p
->pfik_tzero
) {
683 p
->pfik_tzero
= pf_calendar_time_second();
685 pfi_kif_ref(p
, PFI_KIF_REF_RULE
);
687 /* return the user space version of pfi_kif */
688 bzero(&u
, sizeof(u
));
689 bcopy(p
->pfik_name
, &u
.pfik_name
, sizeof(u
.pfik_name
));
690 bcopy(p
->pfik_packets
, &u
.pfik_packets
,
691 sizeof(u
.pfik_packets
));
692 bcopy(p
->pfik_bytes
, &u
.pfik_bytes
,
693 sizeof(u
.pfik_bytes
));
694 u
.pfik_tzero
= p
->pfik_tzero
;
695 u
.pfik_flags
= p
->pfik_flags
;
696 u
.pfik_states
= p
->pfik_states
;
697 u
.pfik_rules
= p
->pfik_rules
;
699 if (copyout(&u
, buf
, sizeof(u
))) {
700 pfi_kif_unref(p
, PFI_KIF_REF_RULE
);
704 nextp
= RB_NEXT(pfi_ifhead
, &pfi_ifs
, p
);
705 pfi_kif_unref(p
, PFI_KIF_REF_RULE
);
713 pfi_skip_if(const char *filter
, struct pfi_kif
*p
)
717 if (filter
== NULL
|| !*filter
) {
720 if (strcmp(p
->pfik_name
, filter
) == 0) {
721 return 0; /* exact match */
724 if (n
< 1 || n
>= IFNAMSIZ
) {
725 return 1; /* sanity check */
727 if (filter
[n
- 1] >= '0' && filter
[n
- 1] <= '9') {
728 return 1; /* only do exact match in that case */
730 if (strncmp(p
->pfik_name
, filter
, n
)) {
731 return 1; /* prefix doesn't match */
733 return p
->pfik_name
[n
] < '0' || p
->pfik_name
[n
] > '9';
737 pfi_set_flags(const char *name
, int flags
)
741 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
743 RB_FOREACH(p
, pfi_ifhead
, &pfi_ifs
) {
744 if (pfi_skip_if(name
, p
)) {
747 p
->pfik_flags
|= flags
;
753 pfi_clear_flags(const char *name
, int flags
)
757 LCK_MTX_ASSERT(pf_lock
, LCK_MTX_ASSERT_OWNED
);
759 RB_FOREACH(p
, pfi_ifhead
, &pfi_ifs
) {
760 if (pfi_skip_if(name
, p
)) {
763 p
->pfik_flags
&= ~flags
;
768 /* from pf_print_state.c */
770 pfi_unmask(void *addr
)
772 struct pf_addr
*m
= addr
;
773 int i
= 31, j
= 0, b
= 0;
776 while (j
< 4 && m
->addr32
[j
] == 0xffffffff) {
781 tmp
= ntohl(m
->addr32
[j
]);
782 for (i
= 31; tmp
& (1 << i
); --i
) {
786 VERIFY(b
>= 0 && b
<= UINT8_MAX
);