xref: /dragonfly/sys/net/pf/pf_if.c (revision f9993810)
1 /*	$OpenBSD: pf_if.c,v 1.54 2008/06/14 16:55:28 mk 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 "opt_inet.h"
36 #include "opt_inet6.h"
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
41 #include <sys/mbuf.h>
42 #include <sys/eventhandler.h>
43 #include <sys/filio.h>
44 #include <sys/msgport2.h>
45 #include <sys/socket.h>
46 #include <sys/socketvar.h>
47 #include <sys/kernel.h>
48 #include <sys/thread2.h>
49 #include <sys/time.h>
50 #include <sys/lock.h>
51 
52 #include <net/if.h>
53 #include <net/if_var.h>
54 #include <net/if_types.h>
55 #include <net/netisr2.h>
56 #include <net/netmsg2.h>
57 #include <net/route.h>
58 
59 #include <netinet/in.h>
60 #include <netinet/in_var.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/ip.h>
63 #include <netinet/ip_var.h>
64 
65 #include <net/pf/pfvar.h>
66 
67 #ifdef INET6
68 #include <netinet/ip6.h>
69 #endif /* INET6 */
70 
71 struct pfi_kif		*pfi_all = NULL;
72 struct pfi_ifhead	 pfi_ifs;
73 static long		 pfi_update = 1;
74 static struct pfr_addr	*pfi_buffer;
75 static int		 pfi_buffer_cnt;
76 static int		 pfi_buffer_max;
77 
78 static eventhandler_tag	 pfi_attach_cookie;
79 static eventhandler_tag	 pfi_detach_cookie;
80 static eventhandler_tag	 pfi_attach_group_cookie;
81 static eventhandler_tag	 pfi_detach_group_cookie;
82 static eventhandler_tag	 pfi_change_group_cookie;
83 static eventhandler_tag	 pfi_ifaddr_event_cookie;
84 
85 static void	 pfi_kif_update(struct pfi_kif *);
86 static void	 pfi_dynaddr_update(struct pfi_dynaddr *);
87 static void	 pfi_table_update(struct pfr_ktable *, struct pfi_kif *,
88 		    int, int);
89 static void	 pfi_instance_add(struct ifnet *, int, int);
90 static void	 pfi_address_add(struct sockaddr *, int, int);
91 static int	 pfi_if_compare(struct pfi_kif *, struct pfi_kif *);
92 static int	 pfi_skip_if(const char *, struct pfi_kif *);
93 static int	 pfi_unmask(void *);
94 
95 static void	 pfi_attach_ifnet_event(void * __unused, struct ifnet *);
96 static void	 pfi_detach_ifnet_event(void * __unused, struct ifnet *);
97 static void	 pfi_attach_group_event(void * __unused, struct ifg_group *);
98 static void	 pfi_detach_group_event(void * __unused, struct ifg_group *);
99 static void	 pfi_change_group_event(void * __unused, char *);
100 static void	 pfi_ifaddr_event(void * __unused, struct ifnet *,
101 		    enum ifaddr_event __unused, struct ifaddr * __unused);
102 
103 static RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
104 static RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
105 
106 #define PFI_BUFFER_MAX		0x10000
107 static MALLOC_DEFINE(M_PFI, "pf_if", "pf interface");
108 
109 
110 void
111 pfi_initialize(void)
112 {
113 	struct ifnet *ifp;
114 	struct ifg_group *ifg;
115 
116 	pfi_attach_cookie = EVENTHANDLER_REGISTER(ifnet_attach_event,
117 	    pfi_attach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
118 	pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_detach_event,
119 	    pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
120 	pfi_attach_group_cookie = EVENTHANDLER_REGISTER(group_attach_event,
121 	    pfi_attach_group_event, NULL, EVENTHANDLER_PRI_ANY);
122 	pfi_detach_group_cookie = EVENTHANDLER_REGISTER(group_detach_event,
123 	    pfi_detach_group_event, NULL, EVENTHANDLER_PRI_ANY);
124 	pfi_change_group_cookie = EVENTHANDLER_REGISTER(group_change_event,
125 	    pfi_change_group_event, NULL, EVENTHANDLER_PRI_ANY);
126 	pfi_ifaddr_event_cookie = EVENTHANDLER_REGISTER(ifaddr_event,
127 	    pfi_ifaddr_event, NULL, EVENTHANDLER_PRI_ANY);
128 
129 	pfi_buffer_max = 64;
130 	pfi_buffer = kmalloc(pfi_buffer_max * sizeof(*pfi_buffer),
131 	    M_PFI, M_WAITOK);
132 
133 	if ((pfi_all = pfi_kif_get(IFG_ALL)) == NULL)
134 		panic("%s: pfi_kif_get(IFG_ALL) failed", __func__);
135 
136 	ifgroup_lockmgr(LK_SHARED);
137 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
138 		pfi_attach_ifgroup(ifg);
139 	ifgroup_lockmgr(LK_RELEASE);
140 
141 	/* XXX ALMOST MPSAFE */
142 	ifnet_lock();
143 	TAILQ_FOREACH(ifp, &ifnetlist, if_link)
144 		pfi_attach_ifnet(ifp);
145 	ifnet_unlock();
146 }
147 
148 void
149 pfi_cleanup(void)
150 {
151 	struct pfi_kif *kif;
152 
153 	while ((kif = RB_MIN(pfi_ifhead, &pfi_ifs))) {
154 		RB_REMOVE(pfi_ifhead, &pfi_ifs, kif);
155 		if (kif->pfik_group)
156 			kif->pfik_group->ifg_pf_kif = NULL;
157 		if (kif->pfik_ifp)
158 			kif->pfik_ifp->if_pf_kif = NULL;
159 		kfree(kif, M_PFI);
160 	}
161 	kfree(pfi_buffer, M_PFI);
162 	pfi_buffer = NULL;
163 	pfi_all = NULL;
164 
165 	EVENTHANDLER_DEREGISTER(ifnet_attach_event, pfi_attach_cookie);
166 	EVENTHANDLER_DEREGISTER(ifnet_detach_event, pfi_detach_cookie);
167 	EVENTHANDLER_DEREGISTER(group_attach_event, pfi_attach_group_cookie);
168 	EVENTHANDLER_DEREGISTER(group_detach_event, pfi_detach_group_cookie);
169 	EVENTHANDLER_DEREGISTER(group_change_event, pfi_change_group_cookie);
170 	EVENTHANDLER_DEREGISTER(ifaddr_event, pfi_ifaddr_event_cookie);
171 }
172 
173 struct pfi_kif *
174 pfi_kif_find(const char *kif_name)
175 {
176 	struct pfi_kif_cmp s;
177 
178 	bzero(&s, sizeof(s));
179 	strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name));
180 
181 	return (RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s));
182 }
183 
184 struct pfi_kif *
185 pfi_kif_get(const char *kif_name)
186 {
187 	struct pfi_kif *kif;
188 
189 	if ((kif = pfi_kif_find(kif_name)))
190 		return (kif);
191 
192 	/*
193 	 * Create a new one
194 	 */
195 	kif = kmalloc(sizeof(*kif), M_PFI, M_WAITOK | M_ZERO);
196 	strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
197 	kif->pfik_tzero = time_second;
198 	TAILQ_INIT(&kif->pfik_dynaddrs);
199 
200 	RB_INSERT(pfi_ifhead, &pfi_ifs, kif);
201 	return (kif);
202 }
203 
204 void
205 pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what)
206 {
207 	switch (what) {
208 	case PFI_KIF_REF_RULE:
209 		kif->pfik_rules++;
210 		break;
211 	case PFI_KIF_REF_STATE:
212 		kif->pfik_states++;
213 		break;
214 	default:
215 		panic("%s: unknown type", __func__);
216 	}
217 }
218 
219 void
220 pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what)
221 {
222 	if (kif == NULL)
223 		return;
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 			kprintf("%s: rules refcount <= 0\n", __func__);
231 			return;
232 		}
233 		kif->pfik_rules--;
234 		break;
235 	case PFI_KIF_REF_STATE:
236 		if (kif->pfik_states <= 0) {
237 			kprintf("%s: state refcount <= 0\n", __func__);
238 			return;
239 		}
240 		kif->pfik_states--;
241 		break;
242 	default:
243 		panic("%s: unknown type", __func__);
244 	}
245 
246 	if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == pfi_all)
247 		return;
248 
249 	if (kif->pfik_rules || kif->pfik_states)
250 		return;
251 
252 	RB_REMOVE(pfi_ifhead, &pfi_ifs, kif);
253 	kfree(kif, M_PFI);
254 }
255 
256 int
257 pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif)
258 {
259 	struct ifg_list	*p;
260 
261 	if (rule_kif == NULL || rule_kif == packet_kif)
262 		return (1);
263 
264 	if (rule_kif->pfik_group != NULL) {
265 		ifgroup_lockmgr(LK_SHARED);
266 		TAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next) {
267 			if (p->ifgl_group == rule_kif->pfik_group) {
268 				ifgroup_lockmgr(LK_RELEASE);
269 				return (1);
270 			}
271 		}
272 		ifgroup_lockmgr(LK_RELEASE);
273 	}
274 
275 	return (0);
276 }
277 
278 void
279 pfi_attach_ifnet(struct ifnet *ifp)
280 {
281 	struct pfi_kif *kif;
282 
283 	if (ifp->if_dunit == IF_DUNIT_NONE)
284 		return;
285 
286 	crit_enter();
287 	pfi_update++;
288 	if ((kif = pfi_kif_get(ifp->if_xname)) == NULL)
289 		panic("%s: pfi_kif_get failed", __func__);
290 	kif->pfik_ifp = ifp;
291 	ifp->if_pf_kif = kif;
292 	pfi_kif_update(kif);
293 	crit_exit();
294 }
295 
296 void
297 pfi_detach_ifnet(struct ifnet *ifp)
298 {
299 	struct pfi_kif *kif;
300 
301 	if ((kif = (struct pfi_kif *)ifp->if_pf_kif) == NULL)
302 		return;
303 
304 	crit_enter();
305 	pfi_update++;
306 	pfi_kif_update(kif);
307 	kif->pfik_ifp = NULL;
308 	ifp->if_pf_kif = NULL;
309 	pfi_kif_unref(kif, PFI_KIF_REF_NONE);
310 	crit_exit();
311 }
312 
313 void
314 pfi_attach_ifgroup(struct ifg_group *ifg)
315 {
316 	struct pfi_kif *kif;
317 
318 	crit_enter();
319 	pfi_update++;
320 	if ((kif = pfi_kif_get(ifg->ifg_group)) == NULL)
321 		panic("%s: pfi_kif_get failed", __func__);
322 	kif->pfik_group = ifg;
323 	ifg->ifg_pf_kif = kif;
324 	crit_exit();
325 }
326 
327 void
328 pfi_detach_ifgroup(struct ifg_group *ifg)
329 {
330 	struct pfi_kif *kif;
331 
332 	if ((kif = (struct pfi_kif *)ifg->ifg_pf_kif) == NULL)
333 		return;
334 
335 	crit_enter();
336 	pfi_update++;
337 	kif->pfik_group = NULL;
338 	ifg->ifg_pf_kif = NULL;
339 	pfi_kif_unref(kif, PFI_KIF_REF_NONE);
340 	crit_exit();
341 }
342 
343 void
344 pfi_group_change(const char *group)
345 {
346 	struct pfi_kif *kif;
347 
348 	crit_enter();
349 	pfi_update++;
350 	if ((kif = pfi_kif_get(group)) == NULL)
351 		panic("%s: pfi_kif_get failed", __func__);
352 	pfi_kif_update(kif);
353 	crit_exit();
354 }
355 
356 int
357 pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
358 {
359 	switch (af) {
360 #ifdef INET
361 	case AF_INET:
362 		switch (dyn->pfid_acnt4) {
363 		case 0:
364 			return (0);
365 		case 1:
366 			return (PF_MATCHA(0, &dyn->pfid_addr4,
367 			    &dyn->pfid_mask4, a, AF_INET));
368 		default:
369 			return (pfr_match_addr(dyn->pfid_kt, a, AF_INET));
370 		}
371 		break;
372 #endif /* INET */
373 #ifdef INET6
374 	case AF_INET6:
375 		switch (dyn->pfid_acnt6) {
376 		case 0:
377 			return (0);
378 		case 1:
379 			return (PF_MATCHA(0, &dyn->pfid_addr6,
380 			    &dyn->pfid_mask6, a, AF_INET6));
381 		default:
382 			return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6));
383 		}
384 		break;
385 #endif /* INET6 */
386 	default:
387 		return (0);
388 	}
389 }
390 
391 int
392 pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
393 {
394 	struct pfi_dynaddr	*dyn;
395 	char			 tblname[PF_TABLE_NAME_SIZE];
396 	struct pf_ruleset	*ruleset = NULL;
397 	int			 rv = 0;
398 
399 	if (aw->type != PF_ADDR_DYNIFTL)
400 		return (0);
401 	if ((dyn = kmalloc(sizeof(struct pfi_dynaddr), M_PFI,
402 			   M_WAITOK | M_NULLOK | M_ZERO)) == NULL) {
403 		return (1);
404 	}
405 
406 	crit_enter();
407 	if (strcmp(aw->v.ifname, "self") == 0)
408 		dyn->pfid_kif = pfi_kif_get(IFG_ALL);
409 	else
410 		dyn->pfid_kif = pfi_kif_get(aw->v.ifname);
411 	if (dyn->pfid_kif == NULL) {
412 		rv = 1;
413 		goto _bad;
414 	}
415 	pfi_kif_ref(dyn->pfid_kif, PFI_KIF_REF_RULE);
416 
417 	dyn->pfid_net = pfi_unmask(&aw->v.a.mask);
418 	if (af == AF_INET && dyn->pfid_net == 32)
419 		dyn->pfid_net = 128;
420 	strlcpy(tblname, aw->v.ifname, sizeof(tblname));
421 	if (aw->iflags & PFI_AFLAG_NETWORK)
422 		strlcat(tblname, ":network", sizeof(tblname));
423 	if (aw->iflags & PFI_AFLAG_BROADCAST)
424 		strlcat(tblname, ":broadcast", sizeof(tblname));
425 	if (aw->iflags & PFI_AFLAG_PEER)
426 		strlcat(tblname, ":peer", sizeof(tblname));
427 	if (aw->iflags & PFI_AFLAG_NOALIAS)
428 		strlcat(tblname, ":0", sizeof(tblname));
429 	if (dyn->pfid_net != 128)
430 		ksnprintf(tblname + strlen(tblname),
431 		    sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net);
432 	if ((ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR)) == NULL) {
433 		rv = 1;
434 		goto _bad;
435 	}
436 
437 	if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname)) == NULL) {
438 		rv = 1;
439 		goto _bad;
440 	}
441 
442 	dyn->pfid_kt->pfrkt_flags |= PFR_TFLAG_ACTIVE;
443 	dyn->pfid_iflags = aw->iflags;
444 	dyn->pfid_af = af;
445 
446 	TAILQ_INSERT_TAIL(&dyn->pfid_kif->pfik_dynaddrs, dyn, entry);
447 	aw->p.dyn = dyn;
448 	pfi_kif_update(dyn->pfid_kif);
449 	crit_exit();
450 	return (0);
451 
452 _bad:
453 	if (dyn->pfid_kt != NULL)
454 		pfr_detach_table(dyn->pfid_kt);
455 	if (ruleset != NULL)
456 		pf_remove_if_empty_ruleset(ruleset);
457 	if (dyn->pfid_kif != NULL)
458 		pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE);
459 	kfree(dyn, M_PFI);
460 	crit_exit();
461 	return (rv);
462 }
463 
464 static void
465 pfi_kif_update(struct pfi_kif *kif)
466 {
467 	struct ifg_list		*ifgl;
468 	struct pfi_dynaddr	*p;
469 
470 	/* update all dynaddr */
471 	TAILQ_FOREACH(p, &kif->pfik_dynaddrs, entry)
472 		pfi_dynaddr_update(p);
473 
474 	/* and for all groups that the kif belongs to */
475 	if (kif->pfik_ifp != NULL) {
476 		ifgroup_lockmgr(LK_SHARED);
477 		TAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_next) {
478 			pfi_kif_update((struct pfi_kif *)
479 			    ifgl->ifgl_group->ifg_pf_kif);
480 		}
481 		ifgroup_lockmgr(LK_RELEASE);
482 	}
483 }
484 
485 static void
486 pfi_dynaddr_update(struct pfi_dynaddr *dyn)
487 {
488 	struct pfi_kif		*kif;
489 	struct pfr_ktable	*kt;
490 
491 	if (dyn == NULL || dyn->pfid_kif == NULL || dyn->pfid_kt == NULL)
492 		panic("%s: bad argument", __func__);
493 
494 	kif = dyn->pfid_kif;
495 	kt = dyn->pfid_kt;
496 
497 	if (kt->pfrkt_larg != pfi_update) {
498 		/* this table needs to be brought up-to-date */
499 		pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags);
500 		kt->pfrkt_larg = pfi_update;
501 	}
502 	pfr_dynaddr_update(kt, dyn);
503 }
504 
505 static void
506 pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
507 {
508 	int			 e, size2 = 0;
509 	struct ifg_member	*ifgm;
510 
511 	pfi_buffer_cnt = 0;
512 
513 	if (kif->pfik_ifp != NULL) {
514 		pfi_instance_add(kif->pfik_ifp, net, flags);
515 	} else if (kif->pfik_group != NULL) {
516 		ifgroup_lockmgr(LK_SHARED);
517 		TAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)
518 			pfi_instance_add(ifgm->ifgm_ifp, net, flags);
519 		ifgroup_lockmgr(LK_RELEASE);
520 	}
521 
522 	if ((e = pfr_set_addrs(&kt->pfrkt_t, pfi_buffer, pfi_buffer_cnt,
523 			       &size2, NULL, NULL, NULL, 0,
524 			       PFR_TFLAG_ALLMASK))) {
525 		kprintf("%s: cannot set %d new addresses into table %s: %d\n",
526 		    __func__, pfi_buffer_cnt, kt->pfrkt_name, e);
527 	}
528 }
529 
530 
531 struct netmsg_pfiadd {
532 	struct netmsg_base	base;
533 	struct ifnet		*ifp;
534 	int			net;
535 	int			flags;
536 };
537 
538 static void
539 pfi_instance_add_dispatch(netmsg_t nmsg)
540 {
541 	struct netmsg_pfiadd *msg = (struct netmsg_pfiadd *)nmsg;
542 	struct ifaddr_container *ifac;
543 	int got4 = 0, got6 = 0;
544 	int net2, af;
545 	struct ifnet *ifp = msg->ifp;
546 	int net = msg->net, flags = msg->flags;
547 
548 	if (ifp == NULL)
549 		goto done;
550 	/*
551 	 * The ifaddr processing in the following loop will block,
552 	 * however, this function is called in netisr0, in which
553 	 * ifaddr list changes happen, so we don't care about the
554 	 * blockness of the ifaddr processing here.
555 	 */
556 	TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
557 		struct ifaddr *ia = ifac->ifa;
558 
559 		if (ia->ifa_addr == NULL)
560 			continue;
561 		af = ia->ifa_addr->sa_family;
562 		if (af != AF_INET && af != AF_INET6)
563 			continue;
564 		/*
565 		 * XXX: For point-to-point interfaces, (ifname:0) and IPv4,
566 		 *	jump over address without a proper route to work
567 		 *	around a problem with ppp not fully removing the
568 		 *	address used during IPCP.
569 		 */
570 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
571 		    !(ia->ifa_flags & IFA_ROUTE) &&
572 		    (flags & PFI_AFLAG_NOALIAS) && (af == AF_INET))
573 			continue;
574 		if ((flags & PFI_AFLAG_BROADCAST) && af == AF_INET6)
575 			continue;
576 		if ((flags & PFI_AFLAG_BROADCAST) &&
577 		    !(ifp->if_flags & IFF_BROADCAST))
578 			continue;
579 		if ((flags & PFI_AFLAG_PEER) &&
580 		    !(ifp->if_flags & IFF_POINTOPOINT))
581 			continue;
582 		if ((flags & (PFI_AFLAG_NETWORK | PFI_AFLAG_NOALIAS)) &&
583 		    af == AF_INET6 &&
584 		    IN6_IS_ADDR_LINKLOCAL(
585 		    &((struct sockaddr_in6 *)ia->ifa_addr)->sin6_addr))
586 			continue;
587 		if (flags & PFI_AFLAG_NOALIAS) {
588 			if (af == AF_INET && got4)
589 				continue;
590 			if (af == AF_INET6 && got6)
591 				continue;
592 		}
593 		if (af == AF_INET)
594 			got4 = 1;
595 		else if (af == AF_INET6)
596 			got6 = 1;
597 		net2 = net;
598 		if (net2 == 128 && (flags & PFI_AFLAG_NETWORK)) {
599 			if (af == AF_INET)
600 				net2 = pfi_unmask(&((struct sockaddr_in *)
601 				    ia->ifa_netmask)->sin_addr);
602 			else if (af == AF_INET6)
603 				net2 = pfi_unmask(&((struct sockaddr_in6 *)
604 				    ia->ifa_netmask)->sin6_addr);
605 		}
606 		if (af == AF_INET && net2 > 32)
607 			net2 = 32;
608 		if (flags & PFI_AFLAG_BROADCAST)
609 			pfi_address_add(ia->ifa_broadaddr, af, net2);
610 		else if (flags & PFI_AFLAG_PEER)
611 			pfi_address_add(ia->ifa_dstaddr, af, net2);
612 		else
613 			pfi_address_add(ia->ifa_addr, af, net2);
614 	}
615 done:
616 	netisr_replymsg(&nmsg->base, 0);
617 }
618 
619 static void
620 pfi_instance_add(struct ifnet *ifp, int net, int flags)
621 {
622 	struct netmsg_pfiadd msg;
623 
624 	netmsg_init(&msg.base, NULL, &curthread->td_msgport, 0,
625 	    pfi_instance_add_dispatch);
626 	msg.ifp = ifp;
627 	msg.net = net;
628 	msg.flags = flags;
629 	netisr_domsg(&msg.base, 0);
630 }
631 
632 static void
633 pfi_address_add(struct sockaddr *sa, int af, int net)
634 {
635 	struct pfr_addr	*p;
636 	int		 i;
637 
638 	if (pfi_buffer_cnt >= pfi_buffer_max) {
639 		int		 new_max = pfi_buffer_max * 2;
640 
641 		if (new_max > PFI_BUFFER_MAX) {
642 			kprintf("%s: address buffer full (%d/%d)\n", __func__,
643 			    pfi_buffer_cnt, PFI_BUFFER_MAX);
644 			return;
645 		}
646 		p = kmalloc(new_max * sizeof(*pfi_buffer), M_PFI, M_WAITOK);
647 		memcpy(pfi_buffer, p, pfi_buffer_cnt * sizeof(*pfi_buffer));
648 		/* no need to zero buffer */
649 		kfree(pfi_buffer, M_PFI);
650 		pfi_buffer = p;
651 		pfi_buffer_max = new_max;
652 	}
653 	if (af == AF_INET && net > 32)
654 		net = 128;
655 	p = pfi_buffer + pfi_buffer_cnt++;
656 	bzero(p, sizeof(*p));
657 	p->pfra_af = af;
658 	p->pfra_net = net;
659 	if (af == AF_INET)
660 		p->pfra_ip4addr = ((struct sockaddr_in *)sa)->sin_addr;
661 	else if (af == AF_INET6) {
662 		p->pfra_ip6addr = ((struct sockaddr_in6 *)sa)->sin6_addr;
663 		if (IN6_IS_SCOPE_EMBED(&p->pfra_ip6addr))
664 			p->pfra_ip6addr.s6_addr16[1] = 0;
665 	}
666 	/* mask network address bits */
667 	if (net < 128)
668 		((caddr_t)p)[p->pfra_net/8] &= ~(0xFF >> (p->pfra_net%8));
669 	for (i = (p->pfra_net+7)/8; i < sizeof(p->pfra_u); i++)
670 		((caddr_t)p)[i] = 0;
671 }
672 
673 void
674 pfi_dynaddr_remove(struct pf_addr_wrap *aw)
675 {
676 	if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
677 	    aw->p.dyn->pfid_kif == NULL || aw->p.dyn->pfid_kt == NULL)
678 		return;
679 
680 	crit_enter();
681 	TAILQ_REMOVE(&aw->p.dyn->pfid_kif->pfik_dynaddrs, aw->p.dyn, entry);
682 	pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE);
683 	aw->p.dyn->pfid_kif = NULL;
684 	pfr_detach_table(aw->p.dyn->pfid_kt);
685 	aw->p.dyn->pfid_kt = NULL;
686 	kfree(aw->p.dyn, M_PFI);
687 	aw->p.dyn = NULL;
688 	crit_exit();
689 }
690 
691 void
692 pfi_dynaddr_copyout(struct pf_addr_wrap *aw)
693 {
694 	if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
695 	    aw->p.dyn->pfid_kif == NULL)
696 		return;
697 	aw->p.dyncnt = aw->p.dyn->pfid_acnt4 + aw->p.dyn->pfid_acnt6;
698 }
699 
700 static int
701 pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
702 {
703 	return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ));
704 }
705 
706 void
707 pfi_update_status(const char *name, struct pf_status *pfs)
708 {
709 	struct pfi_kif		*p;
710 	struct pfi_kif_cmp	 key;
711 	struct ifg_member	 p_member, *ifgm;
712 	TAILQ_HEAD(, ifg_member) ifg_members;
713 	int			 i, j, k;
714 
715 	strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
716 	crit_enter();
717 	p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key);
718 	if (p == NULL) {
719 		crit_exit();
720 		return;
721 	}
722 	if (p->pfik_group != NULL) {
723 		bcopy(&p->pfik_group->ifg_members, &ifg_members,
724 		    sizeof(ifg_members));
725 	} else {
726 		/* build a temporary list for p only */
727 		bzero(&p_member, sizeof(p_member));
728 		p_member.ifgm_ifp = p->pfik_ifp;
729 		TAILQ_INIT(&ifg_members);
730 		TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
731 	}
732 	if (pfs) {
733 		bzero(pfs->pcounters, sizeof(pfs->pcounters));
734 		bzero(pfs->bcounters, sizeof(pfs->bcounters));
735 	}
736 	ifgroup_lockmgr(LK_SHARED);
737 	TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
738 		if (ifgm->ifgm_ifp == NULL ||
739 		    ifgm->ifgm_ifp->if_pf_kif == NULL)
740 			continue;
741 		p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
742 
743 		/* just clear statistics */
744 		if (pfs == NULL) {
745 			bzero(p->pfik_packets, sizeof(p->pfik_packets));
746 			bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
747 			p->pfik_tzero = time_second;
748 			continue;
749 		}
750 		for (i = 0; i < 2; i++)
751 			for (j = 0; j < 2; j++)
752 				for (k = 0; k < 2; k++) {
753 					pfs->pcounters[i][j][k] +=
754 						p->pfik_packets[i][j][k];
755 					pfs->bcounters[i][j] +=
756 						p->pfik_bytes[i][j][k];
757 				}
758 	}
759 	ifgroup_lockmgr(LK_RELEASE);
760 	crit_exit();
761 }
762 
763 int
764 pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
765 {
766 	struct pfi_kif	*p, *nextp;
767 	int		 n = 0;
768 
769 	crit_enter();
770 	for (p = RB_MIN(pfi_ifhead, &pfi_ifs); p; p = nextp) {
771 		nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
772 		if (pfi_skip_if(name, p))
773 			continue;
774 		if (*size > n++) {
775 			if (!p->pfik_tzero)
776 				p->pfik_tzero = time_second;
777 			pfi_kif_ref(p, PFI_KIF_REF_RULE);
778 			if (copyout(p, buf++, sizeof(*buf))) {
779 				pfi_kif_unref(p, PFI_KIF_REF_RULE);
780 				crit_exit();
781 				return (EFAULT);
782 			}
783 			nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
784 			pfi_kif_unref(p, PFI_KIF_REF_RULE);
785 		}
786 	}
787 	crit_exit();
788 	*size = n;
789 	return (0);
790 }
791 
792 static int
793 pfi_skip_if(const char *filter, struct pfi_kif *p)
794 {
795 	struct ifg_list *ifg;
796 	int	         n;
797 
798 	if (filter == NULL || !*filter)
799 		return (0);
800 	if (strcmp(p->pfik_name, filter) == 0)
801 		return (0);	/* exact match */
802 	n = strlen(filter);
803 	if (n < 1 || n >= IFNAMSIZ)
804 		return (1);	/* sanity check */
805 	if (filter[n-1] >= '0' && filter[n-1] <= '9')
806 		return (1);	/* group names may not end in a digit */
807 	if (p->pfik_ifp != NULL) {
808 		ifgroup_lockmgr(LK_SHARED);
809 		TAILQ_FOREACH(ifg, &p->pfik_ifp->if_groups, ifgl_next) {
810 			if (strcmp(ifg->ifgl_group->ifg_group, filter) == 0) {
811 				ifgroup_lockmgr(LK_RELEASE);
812 				return (0); /* iface is in group "filter" */
813 			}
814 		}
815 		ifgroup_lockmgr(LK_RELEASE);
816 	}
817 	return (1);
818 }
819 
820 int
821 pfi_set_flags(const char *name, int flags)
822 {
823 	struct pfi_kif	*p;
824 
825 	crit_enter();
826 	RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
827 		if (pfi_skip_if(name, p))
828 			continue;
829 		p->pfik_flags |= flags;
830 	}
831 	crit_exit();
832 	return (0);
833 }
834 
835 int
836 pfi_clear_flags(const char *name, int flags)
837 {
838 	struct pfi_kif	*p;
839 
840 	crit_enter();
841 	RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
842 		if (pfi_skip_if(name, p))
843 			continue;
844 		p->pfik_flags &= ~flags;
845 	}
846 	crit_exit();
847 	return (0);
848 }
849 
850 /* from pf_print_state.c */
851 static int
852 pfi_unmask(void *addr)
853 {
854 	struct pf_addr *m = addr;
855 	int i = 31, j = 0, b = 0;
856 	u_int32_t tmp;
857 
858 	while (j < 4 && m->addr32[j] == 0xffffffff) {
859 		b += 32;
860 		j++;
861 	}
862 	if (j < 4) {
863 		tmp = ntohl(m->addr32[j]);
864 		for (i = 31; tmp & (1 << i); --i)
865 			b++;
866 	}
867 	return (b);
868 }
869 
870 
871 /*
872  * eventhandler events
873  */
874 
875 static void
876 pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp)
877 {
878 	pfi_attach_ifnet(ifp);
879 }
880 
881 static void
882 pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
883 {
884 	pfi_detach_ifnet(ifp);
885 }
886 
887 static void
888 pfi_attach_group_event(void *arg __unused, struct ifg_group *ifg)
889 {
890 	pfi_attach_ifgroup(ifg);
891 }
892 
893 static void
894 pfi_detach_group_event(void *arg __unused, struct ifg_group *ifg)
895 {
896 	pfi_detach_ifgroup(ifg);
897 }
898 
899 static void
900 pfi_change_group_event(void *arg __unused, char *gname)
901 {
902 	pfi_group_change(gname);
903 }
904 
905 static void
906 pfi_ifaddr_event(void *arg __unused, struct ifnet *ifp,
907 		 enum ifaddr_event event __unused,
908 		 struct ifaddr *ifa __unused)
909 {
910 	if (ifp && ifp->if_pf_kif) {
911 		crit_enter();
912 		pfi_update++;
913 		pfi_kif_update(ifp->if_pf_kif);
914 		crit_exit();
915 	}
916 }
917