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 INET6
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')
68#define islower(c)	((c) >= 'a' && (c) <= 'z')
69#define isalpha(c)	(isupper(c)||islower(c))
70
71struct pfi_kif		 *pfi_all = NULL;
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);
92RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
93
94#define PFI_BUFFER_MAX		0x10000
95#define PFI_MTYPE		M_PF
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_MTYPE, mflags|M_ZERO);
103	if (kif == NULL)
104		return (NULL);
105	strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
106	kif->pfik_tzero = gettime();
107	TAILQ_INIT(&kif->pfik_dynaddrs);
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_ANY;
112		kif->pfik_flags_new |= PFI_IFLAG_ANY;
113	}
114
115	return (kif);
116}
117
118void
119pfi_kif_free(struct pfi_kif *kif)
120{
121	if (kif == NULL)
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_MTYPE, 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)	/* already initialized */
141		return;
142
143	pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, IPL_SOFTNET, 0,
144	    "pfiaddrpl", NULL);
145	pfi_buffer_max = 64;
146	pfi_buffer = mallocarray(pfi_buffer_max, sizeof(*pfi_buffer),
147	    PFI_MTYPE, M_WAITOK);
148
149	pfi_all = pfi_kif_alloc(IFG_ALL, M_WAITOK);
150
151	if (RB_INSERT(pfi_ifhead, &pfi_ifs, pfi_all) != NULL)
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();
161
162	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));
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();
173
174	if ((kif = pfi_kif_find(kif_name)))
175		return (kif);
176
177	/* create new one */
178	if ((prealloc == NULL) || (*prealloc == NULL)) {
179		kif = pfi_kif_alloc(kif_name, M_NOWAIT);
180		if (kif == NULL)
181			return (NULL);
182	} else {
183		kif = *prealloc;
184		*prealloc = NULL;
185	}
186
187	RB_INSERT(pfi_ifhead, &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();
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)
221		return;
222
223	PF_ASSERT_LOCKED();
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,
231			    "pfi_kif_unref (%s): rules refcount <= 0",
232			    kif->pfik_name);
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,
240			    "pfi_kif_unref (%s): state refcount <= 0",
241			    kif->pfik_name);
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,
249			    "pfi_kif_unref (%s): route refcount <= 0",
250			    kif->pfik_name);
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,
258			    "pfi_kif_unref (%s): src-node refcount <= 0",
259			    kif->pfik_name);
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,
267			    "pfi_kif_unref (%s): flags refcount <= 0",
268			    kif->pfik_name);
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 || kif->pfik_group != NULL || 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);
285	free(kif, PFI_MTYPE, 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 || rule_kif == packet_kif)
294		return (1);
295
296	if (rule_kif->pfik_group != NULL)
297		TAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next)
298			if (p->ifgl_group == rule_kif->pfik_group)
299				return (1);
300
301	if (rule_kif->pfik_flags & PFI_IFLAG_ANY && packet_kif->pfik_ifp &&
302	    !(packet_kif->pfik_ifp->if_flags & IFF_LOOPBACK))
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();
315	pfi_initialize();
316	pfi_update++;
317	if ((kif = pfi_kif_get(ifp->if_xname, NULL)) == NULL)
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_MTYPE, M_WAITOK);
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();
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)
339		return;
340
341	PF_LOCK();
342	pfi_update++;
343	t = kif->pfik_ah_cookie;
344	kif->pfik_ah_cookie = NULL;
345	if_addrhook_del(ifp, t);
346	free(t, PFI_MTYPE, sizeof(*t));
347
348	pfi_kif_update(kif);
349
350	kif->pfik_ifp = NULL;
351	ifp->if_pf_kif = NULL;
352	pfi_kif_unref(kif, PFI_KIF_REF_NONE);
353	PF_UNLOCK();
354}
355
356void
357pfi_attach_ifgroup(struct ifg_group *ifg)
358{
359	struct pfi_kif	*kif;
360
361	PF_LOCK();
362	pfi_initialize();
363	pfi_update++;
364	if ((kif = pfi_kif_get(ifg->ifg_group, NULL)) == NULL)
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();
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)
378		return;
379
380	PF_LOCK();
381	pfi_update++;
382
383	kif->pfik_group = NULL;
384	ifg->ifg_pf_kif = NULL;
385	pfi_kif_unref(kif, PFI_KIF_REF_NONE);
386	PF_UNLOCK();
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)) == NULL)
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();
405	pfi_group_change(group);
406	pfi_xcommit();
407	PF_UNLOCK();
408}
409
410void
411pfi_group_addmember(const char *group)
412{
413	PF_LOCK();
414	pfi_group_change(group);
415	pfi_xcommit();
416	PF_UNLOCK();
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_INET:
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_INET));
430		default:
431			return (pfr_match_addr(dyn->pfid_kt, a, AF_INET));
432		}
433		break;
434#ifdef INET6
435	case AF_INET6:
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_INET6));
442		default:
443			return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6));
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_SIZE];
457	struct pf_ruleset	*ruleset = NULL;
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_LIMITFAIL|PR_ZERO)) == NULL)
463		return (1);
464
465	if (!strcmp(aw->v.ifname, "self"))
466		dyn->pfid_kif = pfi_kif_get(IFG_ALL, NULL);
467	else
468		dyn->pfid_kif = pfi_kif_get(aw->v.ifname, NULL);
469	if (dyn->pfid_kif == NULL) {
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_INET && dyn->pfid_net == 32)
477		dyn->pfid_net = 128;
478	strlcpy(tblname, aw->v.ifname, sizeof(tblname));
479	if (aw->iflags & PFI_AFLAG_NETWORK)
480		strlcat(tblname, ":network", sizeof(tblname));
481	if (aw->iflags & PFI_AFLAG_BROADCAST)
482		strlcat(tblname, ":broadcast", sizeof(tblname));
483	if (aw->iflags & PFI_AFLAG_PEER)
484		strlcat(tblname, ":peer", sizeof(tblname));
485	if (aw->iflags & PFI_AFLAG_NOALIAS)
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)) == NULL) {
491		rv = 1;
492		goto _bad;
493	}
494
495	if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, wait)) == NULL) {
496		rv = 1;
497		goto _bad;
498	}
499
500	dyn->pfid_kt->pfrkt_flags |= PFR_TFLAG_ACTIVE;
501	dyn->pfid_iflags = aw->iflags;
502	dyn->pfid_af = af;
503
504	TAILQ_INSERT_TAIL(&dyn->pfid_kif->pfik_dynaddrs, dyn, entry);
505	aw->p.dyn = dyn;
506	pfi_kif_update(dyn->pfid_kif);
507	return (0);
508
509_bad:
510	if (dyn->pfid_kt != NULL)
511		pfr_detach_table(dyn->pfid_kt);
512	if (ruleset != NULL)
513		pf_remove_if_empty_ruleset(ruleset);
514	if (dyn->pfid_kif != NULL)
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)
528		pfi_dynaddr_update(p);
529
530	/* again for all groups kif is member of */
531	if (kif->pfik_ifp != NULL)
532		TAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_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 || dyn->pfid_kif == NULL || dyn->pfid_kt == NULL)
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)
566		pfi_instance_add(kif->pfik_ifp, net, flags);
567	else if (kif->pfik_group != NULL)
568		TAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)
569			pfi_instance_add(ifgm->ifgm_ifp, net, flags);
570
571	if ((e = pfr_set_addrs(&kt->pfrkt_t, pfi_buffer, pfi_buffer_cnt, &size2,
572	    NULL, NULL, NULL, 0, PFR_TFLAG_ALLMASK)))
573		DPFPRINTF(LOG_ERR,
574		    "pfi_table_update: cannot set %d new addresses "
575		    "into table %s: %d", pfi_buffer_cnt, kt->pfrkt_name, e);
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)
586		return;
587	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
588		if (ifa->ifa_addr == NULL)
589			continue;
590		af = ifa->ifa_addr->sa_family;
591		if (af != AF_INET && af != AF_INET6)
592			continue;
593		if ((flags & PFI_AFLAG_BROADCAST) && af == AF_INET6)
594			continue;
595		if ((flags & PFI_AFLAG_BROADCAST) &&
596		    !(ifp->if_flags & IFF_BROADCAST))
597			continue;
598		if ((flags & PFI_AFLAG_PEER) &&
599		    !(ifp->if_flags & IFF_POINTOPOINT))
600			continue;
601		if ((flags & PFI_AFLAG_NETWORK) && af == AF_INET6 &&
602		    IN6_IS_ADDR_LINKLOCAL(
603		    &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr))
604			continue;
605		if (flags & PFI_AFLAG_NOALIAS) {
606			if (af == AF_INET && got4)
607				continue;
608			if (af == AF_INET6 && got6)
609				continue;
610		}
611		if (af == AF_INET)
612			got4 = 1;
613		else if (af == AF_INET6)
614			got6 = 1;
615		net2 = net;
616		if (net2 == 128 && (flags & PFI_AFLAG_NETWORK)) {
617			if (af == AF_INET)
618				net2 = pfi_unmask(&((struct sockaddr_in *)
619				    ifa->ifa_netmask)->sin_addr);
620			else if (af == AF_INET6)
621				net2 = pfi_unmask(&((struct sockaddr_in6 *)
622				    ifa->ifa_netmask)->sin6_addr);
623		}
624		if (af == AF_INET && net2 > 32)
625			net2 = 32;
626		if (flags & PFI_AFLAG_BROADCAST)
627			pfi_address_add(ifa->ifa_broadaddr, af, net2);
628		else if (flags & PFI_AFLAG_PEER)
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_MAX) {
645			DPFPRINTF(LOG_ERR,
646			    "pfi_address_add: address buffer full (%d/%d)",
647			    pfi_buffer_cnt, PFI_BUFFER_MAX);
648			return;
649		}
650		p = mallocarray(new_max, sizeof(*pfi_buffer), PFI_MTYPE,
651		    M_DONTWAIT);
652		if (p == NULL) {
653			DPFPRINTF(LOG_ERR,
654			    "pfi_address_add: no memory to grow buffer "
655			    "(%d/%d)", pfi_buffer_cnt, PFI_BUFFER_MAX);
656			return;
657		}
658		memcpy(p, pfi_buffer, pfi_buffer_max * sizeof(*pfi_buffer));
659		/* no need to zero buffer */
660		free(pfi_buffer, PFI_MTYPE, pfi_buffer_max * sizeof(*pfi_buffer));
661		pfi_buffer = p;
662		pfi_buffer_max = new_max;
663	}
664	if (af == AF_INET && net > 32)
665		net = 128;
666	p = pfi_buffer + pfi_buffer_cnt++;
667	memset(p, 0, sizeof(*p));
668	p->pfra_af = af;
669	p->pfra_net = net;
670	if (af == AF_INET)
671		p->pfra_ip4addr = ((struct sockaddr_in *)sa)->sin_addr;
672	else if (af == AF_INET6) {
673		p->pfra_ip6addr = ((struct sockaddr_in6 *)sa)->sin6_addr;
674		if (IN6_IS_SCOPE_EMBED(&p->pfra_ip6addr))
675			p->pfra_ip6addr.s6_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 ||
688	    aw->p.dyn->pfid_kif == NULL || aw->p.dyn->pfid_kt == NULL)
689		return;
690
691	TAILQ_REMOVE(&aw->p.dyn->pfid_kif->pfik_dynaddrs, aw->p.dyn, entry);
692	pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE);
693	aw->p.dyn->pfid_kif = NULL;
694	pfr_detach_table(aw->p.dyn->pfid_kt);
695	aw->p.dyn->pfid_kt = NULL;
696	pool_put(&pfi_addr_pl, aw->p.dyn);
697	aw->p.dyn = NULL;
698}
699
700void
701pfi_dynaddr_copyout(struct pf_addr_wrap *aw)
702{
703	if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
704	    aw->p.dyn->pfid_kif == NULL)
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();
715
716	PF_LOCK();
717	pfi_update++;
718	pfi_kif_update(kif);
719	PF_UNLOCK();
720}
721
722int
723pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
724{
725	return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ));
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) ifg_members;
735	int			 i, j, k;
736
737	if (*name == '\0' && pfs == NULL) {
738		RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
739			memset(p->pfik_packets, 0, sizeof(p->pfik_packets));
740			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);
748	if (p == NULL) {
749		return;
750	}
751	if (p->pfik_group != NULL) {
752		memcpy(&ifg_members, &p->pfik_group->ifg_members,
753		    sizeof(ifg_members));
754	} else {
755		/* build a temporary list for p only */
756		memset(&p_member, 0, sizeof(p_member));
757		p_member.ifgm_ifp = p->pfik_ifp;
758		TAILQ_INIT(&ifg_members);
759		TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
760	}
761	if (pfs) {
762		memset(pfs->pcounters, 0, sizeof(pfs->pcounters));
763		memset(pfs->bcounters, 0, sizeof(pfs->bcounters));
764	}
765	TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
766		if (ifgm->ifgm_ifp == NULL)
767			continue;
768		p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
769
770		/* just clear statistics */
771		if (pfs == NULL) {
772			memset(p->pfik_packets, 0, sizeof(p->pfik_packets));
773			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) {
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));
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();
813
814	if (filter == NULL || !*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 >= IFNAMSIZ)
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)
824		TAILQ_FOREACH(i, &p->pfik_ifp->if_groups, ifgl_next)
825			if (!strncmp(i->ifgl_group->ifg_group, filter, IFNAMSIZ))
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();
837
838	if (name != NULL && name[0] != '\0') {
839		p = pfi_kif_find(name);
840		if (p == NULL) {
841			n = strlen(name);
842			if (n < 1 || n >= IFNAMSIZ)
843				return (EINVAL);
844
845			if (!isalpha(name[0]))
846				return (EINVAL);
847
848			p = pfi_kif_get(name, NULL);
849			if (p != NULL) {
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);
857				if (ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP))
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)
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();
878
879	if (name != NULL && name[0] != '\0') {
880		p = pfi_kif_find(name);
881		if (p != NULL) {
882			p->pfik_flags_new = p->pfik_flags & ~flags;
883
884			KASSERT((p->pfik_flagrefs == 0) ||
885			    (p->pfik_flagrefs == 1));
886
887			if (!ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP) &&
888			    (p->pfik_flagrefs == 1))
889				pfi_kif_unref(p, PFI_KIF_REF_FLAG);
890		} else
891			return (ESRCH);
892
893	} else
894		RB_FOREACH_SAFE(p, pfi_ifhead, &pfi_ifs, w) {
895			p->pfik_flags_new = p->pfik_flags & ~flags;
896
897			KASSERT((p->pfik_flagrefs == 0) ||
898			    (p->pfik_flagrefs == 1));
899
900			if (!ISSET(p->pfik_flags_new, PFI_IFLAG_SKIP) &&
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();
917
918	RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
919		p->pfik_flags = p->pfik_flags_new;
920		n = strlen(p->pfik_name);
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)
930			TAILQ_FOREACH(g, &ifp->if_groups, ifgl_next) {
931				gkif =
932				    (struct pfi_kif *)g->ifgl_group->ifg_pf_kif;
933				KASSERT(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->addr32[j] == 0xffffffff) {
948		b += 32;
949		j++;
950	}
951	if (j < 4) {
952		tmp = ntohl(m->addr32[j]);
953		for (i = 31; tmp & (1 << i); --i)
954			b++;
955	}
956	return (b);
957}
958
959