db48ab8f840c21a799473b991a301327dcf89bb2
[dragonfly.git] / sys / net / pf / pf_if.c
1 /*      $FreeBSD: src/sys/contrib/pf/net/pf_if.c,v 1.6 2004/09/14 15:20:24 mlaier Exp $ */
2 /*      $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */
3 /* add  $OpenBSD: pf_if.c,v 1.19 2004/08/11 12:06:44 henning Exp $ */
4 /*      $DragonFly: src/sys/net/pf/pf_if.c,v 1.8 2006/12/22 23:44:57 swildner Exp $ */
5
6 /*
7  * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
8  *
9  * Copyright (c) 2001 Daniel Hartmeier
10  * Copyright (c) 2003 Cedric Berger
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  *    - Redistributions of source code must retain the above copyright
18  *      notice, this list of conditions and the following disclaimer.
19  *    - Redistributions in binary form must reproduce the above
20  *      copyright notice, this list of conditions and the following
21  *      disclaimer in the documentation and/or other materials provided
22  *      with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37
38 #include "opt_inet.h"
39 #include "opt_inet6.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/eventhandler.h>
46 #include <sys/filio.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/kernel.h>
50 #include <sys/thread2.h>
51 #include <sys/time.h>
52 #include <vm/vm_zone.h>
53
54 #include <net/if.h>
55 #include <net/if_types.h>
56 #include <net/route.h>
57
58 #include <netinet/in.h>
59 #include <netinet/in_var.h>
60 #include <netinet/in_systm.h>
61 #include <netinet/ip.h>
62 #include <netinet/ip_var.h>
63
64 #include <net/pf/pfvar.h>
65
66 #ifdef INET6
67 #include <netinet/ip6.h>
68 #endif /* INET6 */
69
70 #define ACCEPT_FLAGS(oklist)                    \
71         do {                                    \
72                 if ((flags & ~(oklist)) &       \
73                     PFI_FLAG_ALLMASK)           \
74                         return (EINVAL);        \
75         } while (0)
76
77 #define senderr(e)      do { rv = (e); goto _bad; } while (0)
78
79 struct pfi_kif          **pfi_index2kif;
80 struct pfi_kif           *pfi_self, *pfi_dummy;
81 int                       pfi_indexlim;
82 struct pfi_ifhead         pfi_ifs;
83 struct pfi_statehead      pfi_statehead;
84 int                       pfi_ifcnt;
85 vm_zone_t                 pfi_addr_pl;
86 long                      pfi_update = 1;
87 struct pfr_addr          *pfi_buffer;
88 int                       pfi_buffer_cnt;
89 int                       pfi_buffer_max;
90 char                      pfi_reserved_anchor[PF_ANCHOR_NAME_SIZE] =
91                                 PF_RESERVED_ANCHOR;
92 char                      pfi_interface_ruleset[PF_RULESET_NAME_SIZE] =
93                                 PF_INTERFACE_RULESET;
94
95 eventhandler_tag         pfi_clone_cookie = NULL;
96 eventhandler_tag         pfi_attach_cookie = NULL;
97 eventhandler_tag         pfi_detach_cookie = NULL;
98
99 void             pfi_dynaddr_update(void *);
100 void             pfi_kifaddr_update(void *);
101 void             pfi_table_update(struct pfr_ktable *, struct pfi_kif *,
102                     int, int);
103 void             pfi_instance_add(struct ifnet *, int, int);
104 void             pfi_address_add(struct sockaddr *, int, int);
105 int              pfi_if_compare(struct pfi_kif *, struct pfi_kif *);
106 struct pfi_kif  *pfi_if_create(const char *, struct pfi_kif *, int);
107 void             pfi_copy_group(char *, const char *, int);
108 void             pfi_dynamic_drivers(void);
109 void             pfi_newgroup(const char *, int);
110 int              pfi_skip_if(const char *, struct pfi_kif *, int);
111 int              pfi_unmask(void *);
112 void             pfi_dohooks(struct pfi_kif *);
113 void             pfi_kifaddr_update_event(void *, struct ifnet *);
114 void             pfi_attach_clone_event(void *, struct if_clone *);
115 void             pfi_attach_ifnet_event(void *, struct ifnet *);
116 void             pfi_detach_ifnet_event(void *, struct ifnet *);
117
118 RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
119 RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
120
121 #define PFI_DYNAMIC_BUSES       { "pcmcia", "cardbus", "uhub" }
122 #define PFI_BUFFER_MAX          0x10000
123 MALLOC_DEFINE(PFI_MTYPE, "pf_if", "pf interface table");
124
125 void
126 pfi_initialize(void)
127 {
128         struct ifnet    *ifp;
129
130         if (pfi_self != NULL)   /* already initialized */
131                 return;
132
133         TAILQ_INIT(&pfi_statehead);
134         pfi_buffer_max = 64;
135         pfi_buffer = kmalloc(pfi_buffer_max * sizeof(*pfi_buffer),
136             PFI_MTYPE, M_WAITOK);
137         pfi_self = pfi_if_create("self", NULL, PFI_IFLAG_GROUP);
138         pfi_dynamic_drivers();
139
140         TAILQ_FOREACH(ifp, &ifnet, if_link) {
141                 if (ifp->if_dunit != IF_DUNIT_NONE)
142                         pfi_attach_ifnet(ifp);
143         }
144         pfi_dummy = pfi_if_create("notyet", pfi_self,
145             PFI_IFLAG_GROUP | PFI_IFLAG_DYNAMIC);
146         pfi_attach_cookie = EVENTHANDLER_REGISTER(ifnet_attach_event,
147             pfi_attach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
148         pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_detach_event,
149             pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
150         pfi_clone_cookie = EVENTHANDLER_REGISTER(if_clone_event,
151             pfi_attach_clone_event, NULL, EVENTHANDLER_PRI_ANY);
152 }
153
154 void
155 pfi_cleanup(void)
156 {
157         struct pfi_kif *p, key;
158         struct ifnet *ifp;
159
160         EVENTHANDLER_DEREGISTER(ifnet_attach_event, pfi_attach_cookie);
161         EVENTHANDLER_DEREGISTER(ifnet_detach_event, pfi_detach_cookie);
162         EVENTHANDLER_DEREGISTER(if_clone_event, pfi_clone_cookie);
163
164         /* release PFI_IFLAG_INSTANCE */
165         TAILQ_FOREACH(ifp, &ifnet, if_link) {
166                 strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name));
167                 p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
168                 if (p != NULL)
169                         pfi_detach_ifnet(ifp);
170         }
171
172         /* XXX clear all other interface group */
173         while ((p = RB_MIN(pfi_ifhead, &pfi_ifs))) {
174                 RB_REMOVE(pfi_ifhead, &pfi_ifs, p);
175
176                 kfree(p->pfik_ah_head, PFI_MTYPE);
177                 kfree(p, PFI_MTYPE);
178         }
179         kfree(pfi_index2kif, PFI_MTYPE);
180         kfree(pfi_buffer, PFI_MTYPE);
181         pfi_index2kif = NULL;
182         pfi_buffer = NULL;
183         pfi_self = NULL;
184 }
185
186 /*
187  * Wrapper functions for FreeBSD eventhandler
188  */
189 void
190 pfi_kifaddr_update_event(void *arg, struct ifnet *ifp)
191 {
192         struct pfi_kif *p = arg;
193         
194         /* 
195          * Check to see if it is 'our' interface as we do not have per
196          * interface hooks and thus get an update for every interface.
197          */
198         if (p && p->pfik_ifp == ifp)
199                 pfi_kifaddr_update(p);
200 }
201
202 void
203 pfi_attach_clone_event(void *arg __unused, struct if_clone *ifc)
204 {
205         pfi_attach_clone(ifc);
206 }
207
208 void
209 pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp)
210 {
211         if (ifp->if_dunit != IF_DUNIT_NONE)
212                 pfi_attach_ifnet(ifp);
213 }
214
215 void
216 pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
217 {
218         pfi_detach_ifnet(ifp);
219 }
220
221 void
222 pfi_attach_clone(struct if_clone *ifc)
223 {
224         pfi_initialize();
225         pfi_newgroup(ifc->ifc_name, PFI_IFLAG_CLONABLE);
226 }
227
228 void
229 pfi_attach_ifnet(struct ifnet *ifp)
230 {
231         struct pfi_kif  *p, *q, key;
232         int              realname;
233
234         pfi_initialize();
235         crit_enter();
236         pfi_update++;
237         if (ifp->if_index >= pfi_indexlim) {
238                 /*
239                  * grow pfi_index2kif,  similar to ifindex2ifnet code in if.c
240                  */
241                 size_t m, n, oldlim;
242                 struct pfi_kif **mp, **np;
243
244                 oldlim = pfi_indexlim;
245                 if (pfi_indexlim == 0)
246                         pfi_indexlim = 64;
247                 while (ifp->if_index >= pfi_indexlim)
248                         pfi_indexlim <<= 1;
249
250                 m = oldlim * sizeof(struct pfi_kif *);
251                 mp = pfi_index2kif;
252                 n = pfi_indexlim * sizeof(struct pfi_kif *);
253                 np = kmalloc(n, PFI_MTYPE, M_NOWAIT);
254                 if (np == NULL)
255                         panic("pfi_attach_ifnet: "
256                             "cannot allocate translation table");
257                 bzero(np, n);
258                 if (mp != NULL)
259                         bcopy(mp, np, m);
260                 pfi_index2kif = np;
261                 if (mp != NULL)
262                         kfree(mp, PFI_MTYPE);
263         }
264
265         strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name));
266         p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
267         /* some additional trickery for placeholders */
268         if ((p == NULL) || (p->pfik_parent == pfi_dummy)) {
269                 /* are we looking at a renamed instance or not? */
270                 pfi_copy_group(key.pfik_name, ifp->if_xname,
271                     sizeof(key.pfik_name));
272                 realname = (strncmp(key.pfik_name, ifp->if_dname,
273                     sizeof(key.pfik_name)) == 0);
274                 /* add group */
275                 /* we can change if_xname, hence use if_dname as group id */
276                 pfi_copy_group(key.pfik_name, ifp->if_dname,
277                     sizeof(key.pfik_name));
278                 q = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
279                 if (q == NULL)
280                     q = pfi_if_create(key.pfik_name, pfi_self,
281                         PFI_IFLAG_GROUP|PFI_IFLAG_DYNAMIC);
282                 else if (q->pfik_parent == pfi_dummy) {
283                         q->pfik_parent = pfi_self;
284                         q->pfik_flags = (PFI_IFLAG_GROUP | PFI_IFLAG_DYNAMIC);
285                 }
286                 if (q == NULL)
287                         panic("pfi_attach_ifnet: "
288                             "cannot allocate '%s' group", key.pfik_name);
289
290                 /* add/modify interface */
291                 if (p == NULL)
292                         p = pfi_if_create(ifp->if_xname, q,
293                             realname?PFI_IFLAG_INSTANCE:PFI_IFLAG_PLACEHOLDER);
294                 else {
295                         /* remove from the dummy group */
296                         /* XXX: copy stats? We should not have any!!! */
297                         pfi_dummy->pfik_delcnt++;
298                         TAILQ_REMOVE(&pfi_dummy->pfik_grouphead, p,
299                             pfik_instances);
300                         /* move to the right group */
301                         p->pfik_parent = q;
302                         q->pfik_addcnt++;
303                         TAILQ_INSERT_TAIL(&q->pfik_grouphead, p,
304                             pfik_instances);
305                         if (realname) {
306                                 p->pfik_flags &= ~PFI_IFLAG_PLACEHOLDER;
307                                 p->pfik_flags |= PFI_IFLAG_INSTANCE;
308                         }
309                 }
310                 if (p == NULL)
311                         panic("pfi_attach_ifnet: "
312                             "cannot allocate '%s' interface", ifp->if_xname);
313         } else
314                 q = p->pfik_parent;
315         p->pfik_ifp = ifp;
316         p->pfik_flags |= PFI_IFLAG_ATTACHED;
317         p->pfik_ah_cookie = EVENTHANDLER_REGISTER(ifaddr_event,
318             pfi_kifaddr_update_event, p, EVENTHANDLER_PRI_ANY);
319         pfi_index2kif[ifp->if_index] = p;
320         pfi_dohooks(p);
321         crit_exit();
322 }
323
324 void
325 pfi_detach_ifnet(struct ifnet *ifp)
326 {
327         struct pfi_kif  *p, *q, key;
328
329         strlcpy(key.pfik_name, ifp->if_xname, sizeof(key.pfik_name));
330
331         crit_enter();
332         pfi_update++;
333         p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
334         if (p == NULL) {
335                 kprintf("pfi_detach_ifnet: cannot find %s", ifp->if_xname);
336                 crit_exit();
337                 return;
338         }
339         EVENTHANDLER_DEREGISTER(ifaddr_event, p->pfik_ah_cookie);
340         q = p->pfik_parent;
341         p->pfik_ifp = NULL;
342         p->pfik_flags &= ~PFI_IFLAG_ATTACHED;
343         pfi_index2kif[ifp->if_index] = NULL;
344         pfi_dohooks(p);
345         pfi_maybe_destroy(p);
346         crit_exit();
347 }
348
349 struct pfi_kif *
350 pfi_lookup_create(const char *name)
351 {
352         struct pfi_kif  *p, *q, key;
353
354         crit_enter();
355         p = pfi_lookup_if(name);
356         if (p == NULL) {
357                 pfi_copy_group(key.pfik_name, name, sizeof(key.pfik_name));
358                 q = pfi_lookup_if(key.pfik_name);
359                 if ((q != NULL) && (q->pfik_parent != pfi_dummy))
360                         p = pfi_if_create(name, q, PFI_IFLAG_INSTANCE);
361                 else {
362                         if (pfi_dummy == NULL)
363                                 panic("no 'notyet' dummy group");
364                         p = pfi_if_create(name, pfi_dummy,
365                             PFI_IFLAG_PLACEHOLDER);
366                 }
367         }
368         crit_exit();
369         return (p);
370 }
371
372 struct pfi_kif *
373 pfi_attach_rule(const char *name)
374 {
375         struct pfi_kif  *p;
376
377         p = pfi_lookup_create(name);
378         if (p != NULL)
379                 p->pfik_rules++;
380         return (p);
381 }
382
383 void
384 pfi_detach_rule(struct pfi_kif *p)
385 {
386         if (p == NULL)
387                 return;
388         if (p->pfik_rules > 0)
389                 p->pfik_rules--;
390         else
391                 kprintf("pfi_detach_rule: reference count at 0\n");
392         pfi_maybe_destroy(p);
393 }
394
395 void
396 pfi_attach_state(struct pfi_kif *p)
397 {
398         if (!p->pfik_states++)
399                 TAILQ_INSERT_TAIL(&pfi_statehead, p, pfik_w_states);
400 }
401
402 void
403 pfi_detach_state(struct pfi_kif *p)
404 {
405         if (p == NULL)
406                 return;
407         if (p->pfik_states <= 0) {
408                 kprintf("pfi_detach_state: reference count <= 0\n");
409                 return;
410         }
411         if (!--p->pfik_states)
412                 TAILQ_REMOVE(&pfi_statehead, p, pfik_w_states);
413         pfi_maybe_destroy(p);
414 }
415
416 int
417 pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
418 {
419         struct pfi_dynaddr      *dyn;
420         char                     tblname[PF_TABLE_NAME_SIZE];
421         struct pf_ruleset       *ruleset = NULL;
422         int                      rv = 0;
423
424         if (aw->type != PF_ADDR_DYNIFTL)
425                 return (0);
426         dyn = pool_get(&pfi_addr_pl, PR_NOWAIT);
427         if (dyn == NULL)
428                 return (1);
429         bzero(dyn, sizeof(*dyn));
430
431         crit_enter();
432         dyn->pfid_kif = pfi_attach_rule(aw->v.ifname);
433         if (dyn->pfid_kif == NULL)
434                 senderr(1);
435
436         dyn->pfid_net = pfi_unmask(&aw->v.a.mask);
437         if (af == AF_INET && dyn->pfid_net == 32)
438                 dyn->pfid_net = 128;
439         strlcpy(tblname, aw->v.ifname, sizeof(tblname));
440         if (aw->iflags & PFI_AFLAG_NETWORK)
441                 strlcat(tblname, ":network", sizeof(tblname));
442         if (aw->iflags & PFI_AFLAG_BROADCAST)
443                 strlcat(tblname, ":broadcast", sizeof(tblname));
444         if (aw->iflags & PFI_AFLAG_PEER)
445                 strlcat(tblname, ":peer", sizeof(tblname));
446         if (aw->iflags & PFI_AFLAG_NOALIAS)
447                 strlcat(tblname, ":0", sizeof(tblname));
448         if (dyn->pfid_net != 128)
449                 ksnprintf(tblname + strlen(tblname),
450                     sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net);
451         ruleset = pf_find_or_create_ruleset(pfi_reserved_anchor,
452             pfi_interface_ruleset);
453         if (ruleset == NULL)
454                 senderr(1);
455
456         dyn->pfid_kt = pfr_attach_table(ruleset, tblname);
457         if (dyn->pfid_kt == NULL)
458                 senderr(1);
459
460         dyn->pfid_kt->pfrkt_flags |= PFR_TFLAG_ACTIVE;
461         dyn->pfid_iflags = aw->iflags;
462         dyn->pfid_af = af;
463         dyn->pfid_hook_cookie = hook_establish(dyn->pfid_kif->pfik_ah_head, 1,
464             pfi_dynaddr_update, dyn);
465         if (dyn->pfid_hook_cookie == NULL)
466                 senderr(1);
467
468         aw->p.dyn = dyn;
469         pfi_dynaddr_update(aw->p.dyn);
470         crit_exit();
471         return (0);
472
473 _bad:
474         if (dyn->pfid_kt != NULL)
475                 pfr_detach_table(dyn->pfid_kt);
476         if (ruleset != NULL)
477                 pf_remove_if_empty_ruleset(ruleset);
478         if (dyn->pfid_kif != NULL)
479                 pfi_detach_rule(dyn->pfid_kif);
480         pool_put(&pfi_addr_pl, dyn);
481         crit_exit();
482         return (rv);
483 }
484
485 void
486 pfi_dynaddr_update(void *p)
487 {
488         struct pfi_dynaddr      *dyn = (struct pfi_dynaddr *)p;
489         struct pfi_kif          *kif = dyn->pfid_kif;
490         struct pfr_ktable       *kt = dyn->pfid_kt;
491
492         if (dyn == NULL || kif == NULL || kt == NULL)
493                 panic("pfi_dynaddr_update");
494         if (kt->pfrkt_larg != pfi_update) {
495                 /* this table needs to be brought up-to-date */
496                 pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags);
497                 kt->pfrkt_larg = pfi_update;
498         }
499         pfr_dynaddr_update(kt, dyn);
500 }
501
502 void
503 pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
504 {
505         int                      e, size2 = 0;
506         struct pfi_kif          *p;
507         struct pfr_table         t;
508
509         if ((kif->pfik_flags & PFI_IFLAG_INSTANCE) && kif->pfik_ifp == NULL) {
510                 pfr_clr_addrs(&kt->pfrkt_t, NULL, 0);
511                 return;
512         }
513         pfi_buffer_cnt = 0;
514         if ((kif->pfik_flags & PFI_IFLAG_INSTANCE))
515                 pfi_instance_add(kif->pfik_ifp, net, flags);
516         else if (strcmp(kif->pfik_name, "self")) {
517                 TAILQ_FOREACH(p, &kif->pfik_grouphead, pfik_instances)
518                         pfi_instance_add(p->pfik_ifp, net, flags);
519         } else {
520                 RB_FOREACH(p, pfi_ifhead, &pfi_ifs)
521                         if (p->pfik_flags & PFI_IFLAG_INSTANCE)
522                                 pfi_instance_add(p->pfik_ifp, net, flags);
523         }
524         t = kt->pfrkt_t;
525         t.pfrt_flags = 0;
526         if ((e = pfr_set_addrs(&t, pfi_buffer, pfi_buffer_cnt, &size2,
527             NULL, NULL, NULL, 0)))
528                 kprintf("pfi_table_update: cannot set %d new addresses "
529                     "into table %s: %d\n", pfi_buffer_cnt, kt->pfrkt_name, e);
530 }
531
532 void
533 pfi_instance_add(struct ifnet *ifp, int net, int flags)
534 {
535         struct ifaddr   *ia;
536         int              got4 = 0, got6 = 0;
537         int              net2, af;
538
539         if (ifp == NULL)
540                 return;
541         TAILQ_FOREACH(ia, &ifp->if_addrlist, ifa_list) {
542                 if (ia->ifa_addr == NULL)
543                         continue;
544                 af = ia->ifa_addr->sa_family;
545                 if (af != AF_INET && af != AF_INET6)
546                         continue;
547                 /*
548                  * XXX: For point-to-point interfaces, (ifname:0) and IPv4,
549                  *      jump over address without a proper route to work
550                  *      around a problem with ppp not fully removing the
551                  *      address used during IPCP.
552                  */
553                 if ((ifp->if_flags & IFF_POINTOPOINT) &&
554                     !(ia->ifa_flags & IFA_ROUTE) &&
555                     (flags & PFI_AFLAG_NOALIAS) && (af == AF_INET))
556                         continue;
557                 if ((flags & PFI_AFLAG_BROADCAST) && af == AF_INET6)
558                         continue;
559                 if ((flags & PFI_AFLAG_BROADCAST) &&
560                     !(ifp->if_flags & IFF_BROADCAST))
561                         continue;
562                 if ((flags & PFI_AFLAG_PEER) &&
563                     !(ifp->if_flags & IFF_POINTOPOINT))
564                         continue;
565                 if ((flags & PFI_AFLAG_NETWORK) && af == AF_INET6 &&
566                     IN6_IS_ADDR_LINKLOCAL(
567                     &((struct sockaddr_in6 *)ia->ifa_addr)->sin6_addr))
568                         continue;
569                 if (flags & PFI_AFLAG_NOALIAS) {
570                         if (af == AF_INET && got4)
571                                 continue;
572                         if (af == AF_INET6 && got6)
573                                 continue;
574                 }
575                 if (af == AF_INET)
576                         got4 = 1;
577                 else
578                         got6 = 1;
579                 net2 = net;
580                 if (net2 == 128 && (flags & PFI_AFLAG_NETWORK)) {
581                         if (af == AF_INET) {
582                                 net2 = pfi_unmask(&((struct sockaddr_in *)
583                                     ia->ifa_netmask)->sin_addr);
584                         } else {
585                                 net2 = pfi_unmask(&((struct sockaddr_in6 *)
586                                     ia->ifa_netmask)->sin6_addr);
587                         }
588                 }
589                 if (af == AF_INET && net2 > 32)
590                         net2 = 32;
591                 if (flags & PFI_AFLAG_BROADCAST)
592                         pfi_address_add(ia->ifa_broadaddr, af, net2);
593                 else if (flags & PFI_AFLAG_PEER)
594                         pfi_address_add(ia->ifa_dstaddr, af, net2);
595                 else
596                         pfi_address_add(ia->ifa_addr, af, net2);
597         }
598 }
599
600 void
601 pfi_address_add(struct sockaddr *sa, int af, int net)
602 {
603         struct pfr_addr *p;
604         int              i;
605
606         if (pfi_buffer_cnt >= pfi_buffer_max) {
607                 int              new_max = pfi_buffer_max * 2;
608
609                 if (new_max > PFI_BUFFER_MAX) {
610                         kprintf("pfi_address_add: address buffer full (%d/%d)\n",
611                             pfi_buffer_cnt, PFI_BUFFER_MAX);
612                         return;
613                 }
614                 p = kmalloc(new_max * sizeof(*pfi_buffer), PFI_MTYPE,
615                     M_NOWAIT);
616                 if (p == NULL) {
617                         kprintf("pfi_address_add: no memory to grow buffer "
618                             "(%d/%d)\n", pfi_buffer_cnt, PFI_BUFFER_MAX);
619                         return;
620                 }
621                 memcpy(pfi_buffer, p, pfi_buffer_cnt * sizeof(*pfi_buffer));
622                 /* no need to zero buffer */
623                 kfree(pfi_buffer, PFI_MTYPE);
624                 pfi_buffer = p;
625                 pfi_buffer_max = new_max;
626         }
627         if (af == AF_INET && net > 32)
628                 net = 128;
629         p = pfi_buffer + pfi_buffer_cnt++;
630         bzero(p, sizeof(*p));
631         p->pfra_af = af;
632         p->pfra_net = net;
633         if (af == AF_INET)
634                 p->pfra_ip4addr = ((struct sockaddr_in *)sa)->sin_addr;
635         if (af == AF_INET6) {
636                 p->pfra_ip6addr = ((struct sockaddr_in6 *)sa)->sin6_addr;
637                 if (IN6_IS_ADDR_LINKLOCAL(&p->pfra_ip6addr))
638                         p->pfra_ip6addr.s6_addr16[1] = 0;
639         }
640         /* mask network address bits */
641         if (net < 128)
642                 ((caddr_t)p)[p->pfra_net/8] &= ~(0xFF >> (p->pfra_net%8));
643         for (i = (p->pfra_net+7)/8; i < sizeof(p->pfra_u); i++)
644                 ((caddr_t)p)[i] = 0;
645 }
646
647 void
648 pfi_dynaddr_remove(struct pf_addr_wrap *aw)
649 {
650         if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
651             aw->p.dyn->pfid_kif == NULL || aw->p.dyn->pfid_kt == NULL)
652                 return;
653
654         crit_enter();
655         hook_disestablish(aw->p.dyn->pfid_kif->pfik_ah_head,
656             aw->p.dyn->pfid_hook_cookie);
657         pfi_detach_rule(aw->p.dyn->pfid_kif);
658         aw->p.dyn->pfid_kif = NULL;
659         pfr_detach_table(aw->p.dyn->pfid_kt);
660         aw->p.dyn->pfid_kt = NULL;
661         pool_put(&pfi_addr_pl, aw->p.dyn);
662         aw->p.dyn = NULL;
663         crit_exit();
664 }
665
666 void
667 pfi_dynaddr_copyout(struct pf_addr_wrap *aw)
668 {
669         if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
670             aw->p.dyn->pfid_kif == NULL)
671                 return;
672         aw->p.dyncnt = aw->p.dyn->pfid_acnt4 + aw->p.dyn->pfid_acnt6;
673 }
674
675 void
676 pfi_kifaddr_update(void *v)
677 {
678         crit_enter();
679         pfi_update++;
680         pfi_dohooks(v);
681         crit_exit();
682 }
683
684 int
685 pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
686 {
687         return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ));
688 }
689
690 struct pfi_kif *
691 pfi_if_create(const char *name, struct pfi_kif *q, int flags)
692 {
693         struct pfi_kif *p;
694
695         p = kmalloc(sizeof(*p), PFI_MTYPE, M_NOWAIT);
696         if (p == NULL)
697                 return (NULL);
698         bzero(p, sizeof(*p));
699         p->pfik_ah_head = kmalloc(sizeof(*p->pfik_ah_head), PFI_MTYPE,
700             M_NOWAIT);
701         if (p->pfik_ah_head == NULL) {
702                 kfree(p, PFI_MTYPE);
703                 return (NULL);
704         }
705         bzero(p->pfik_ah_head, sizeof(*p->pfik_ah_head));
706         TAILQ_INIT(p->pfik_ah_head);
707         TAILQ_INIT(&p->pfik_grouphead);
708         strlcpy(p->pfik_name, name, sizeof(p->pfik_name));
709         RB_INIT(&p->pfik_lan_ext);
710         RB_INIT(&p->pfik_ext_gwy);
711         p->pfik_flags = flags;
712         p->pfik_parent = q;
713         p->pfik_tzero = time_second;
714
715         RB_INSERT(pfi_ifhead, &pfi_ifs, p);
716         if (q != NULL) {
717                 q->pfik_addcnt++;
718                 TAILQ_INSERT_TAIL(&q->pfik_grouphead, p, pfik_instances);
719         }
720         pfi_ifcnt++;
721         return (p);
722 }
723
724 int
725 pfi_maybe_destroy(struct pfi_kif *p)
726 {
727         int              i, j, k;
728         struct pfi_kif  *q = p->pfik_parent;
729
730         if ((p->pfik_flags & (PFI_IFLAG_ATTACHED | PFI_IFLAG_GROUP)) ||
731             p->pfik_rules > 0 || p->pfik_states > 0)
732                 if (!(p->pfik_flags & PFI_IFLAG_PLACEHOLDER))
733                         return (0);
734
735         crit_enter();
736         if (q != NULL) {
737                 for (i = 0; i < 2; i++)
738                         for (j = 0; j < 2; j++)
739                                 for (k = 0; k < 2; k++) {
740                                         q->pfik_bytes[i][j][k] +=
741                                             p->pfik_bytes[i][j][k];
742                                         q->pfik_packets[i][j][k] +=
743                                             p->pfik_packets[i][j][k];
744                         /* clear stats in case we return to the dummy group */
745                                         p->pfik_bytes[i][j][k] = 0;
746                                         p->pfik_packets[i][j][k] = 0;
747                                 }
748                 q->pfik_delcnt++;
749                 TAILQ_REMOVE(&q->pfik_grouphead, p, pfik_instances);
750         }
751         if (p->pfik_rules > 0 || p->pfik_states > 0) {
752                 /* move back to the dummy group */
753                 p->pfik_parent = pfi_dummy;
754                 pfi_dummy->pfik_addcnt++;
755                 TAILQ_INSERT_TAIL(&pfi_dummy->pfik_grouphead, p,
756                     pfik_instances);
757                 crit_exit();
758                 return (0);
759         }
760         pfi_ifcnt--;
761         RB_REMOVE(pfi_ifhead, &pfi_ifs, p);
762         crit_exit();
763
764         kfree(p->pfik_ah_head, PFI_MTYPE);
765         kfree(p, PFI_MTYPE);
766         return (1);
767 }
768
769 void
770 pfi_copy_group(char *p, const char *q, int m)
771 {
772         while (m > 1 && *q && !(*q >= '0' && *q <= '9')) {
773                 *p++ = *q++;
774                 m--;
775         }
776         if (m > 0)
777                 *p++ = '\0';
778 }
779
780 void
781 pfi_dynamic_drivers(void)
782 {
783         struct ifnet    *ifp;
784
785 /*
786  * For FreeBSD basically every interface is "dynamic" as we can unload
787  * modules e.g.
788  */
789         TAILQ_FOREACH(ifp, &ifnet, if_link) {
790                 if (ifp->if_dunit == IF_DUNIT_NONE)
791                         continue;
792                 pfi_newgroup(ifp->if_dname, PFI_IFLAG_DYNAMIC);
793         }
794 }
795
796 void
797 pfi_newgroup(const char *name, int flags)
798 {
799         struct pfi_kif  *p;
800
801         p = pfi_lookup_if(name);
802         if (p == NULL)
803                 p = pfi_if_create(name, pfi_self, PFI_IFLAG_GROUP);
804         if (p == NULL) {
805                 kprintf("pfi_newgroup: cannot allocate '%s' group", name);
806                 return;
807         }
808         p->pfik_flags |= flags;
809 }
810
811 void
812 pfi_fill_oldstatus(struct pf_status *pfs)
813 {
814         struct pfi_kif  *p, key;
815         int              i, j, k;
816
817         strlcpy(key.pfik_name, pfs->ifname, sizeof(key.pfik_name));
818         crit_enter();
819         p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
820         if (p == NULL) {
821                 crit_exit();
822                 return;
823         }
824         bzero(pfs->pcounters, sizeof(pfs->pcounters));
825         bzero(pfs->bcounters, sizeof(pfs->bcounters));
826         for (i = 0; i < 2; i++)
827                 for (j = 0; j < 2; j++)
828                         for (k = 0; k < 2; k++) {
829                                 pfs->pcounters[i][j][k] =
830                                         p->pfik_packets[i][j][k];
831                                 pfs->bcounters[i][j] +=
832                                         p->pfik_bytes[i][j][k];
833                         }
834         crit_exit();
835 }
836
837 int
838 pfi_clr_istats(const char *name, int *nzero, int flags)
839 {
840         struct pfi_kif  *p;
841         int              n = 0;
842         long             tzero = time_second;
843
844         crit_enter();
845         ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE);
846         RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
847                 if (pfi_skip_if(name, p, flags))
848                         continue;
849                 bzero(p->pfik_packets, sizeof(p->pfik_packets));
850                 bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
851                 p->pfik_tzero = tzero;
852                 n++;
853         }
854         crit_exit();
855         if (nzero != NULL)
856                 *nzero = n;
857         return (0);
858 }
859
860 int
861 pfi_get_ifaces(const char *name, struct pfi_if *buf, int *size, int flags)
862 {
863         struct pfi_kif  *p;
864         int              n = 0;
865
866         ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE);
867         crit_enter();
868         RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
869                 if (pfi_skip_if(name, p, flags))
870                         continue;
871                 if (*size > n++) {
872                         if (!p->pfik_tzero)
873                                 p->pfik_tzero = boottime.tv_sec;
874                         if (copyout(p, buf++, sizeof(*buf))) {
875                                 crit_exit();
876                                 return (EFAULT);
877                         }
878                 }
879         }
880         crit_exit();
881         *size = n;
882         return (0);
883 }
884
885 struct pfi_kif *
886 pfi_lookup_if(const char *name)
887 {
888         struct pfi_kif  *p, key;
889
890         strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
891         p = RB_FIND(pfi_ifhead, &pfi_ifs, &key);
892         return (p);
893 }
894
895 int
896 pfi_skip_if(const char *filter, struct pfi_kif *p, int f)
897 {
898         int     n;
899
900         if ((p->pfik_flags & PFI_IFLAG_GROUP) && !(f & PFI_FLAG_GROUP))
901                 return (1);
902         if ((p->pfik_flags & PFI_IFLAG_INSTANCE) && !(f & PFI_FLAG_INSTANCE))
903                 return (1);
904         if (filter == NULL || !*filter)
905                 return (0);
906         if (!strcmp(p->pfik_name, filter))
907                 return (0);     /* exact match */
908         n = strlen(filter);
909         if (n < 1 || n >= IFNAMSIZ)
910                 return (1);     /* sanity check */
911         if (filter[n-1] >= '0' && filter[n-1] <= '9')
912                 return (1);     /* only do exact match in that case */
913         if (strncmp(p->pfik_name, filter, n))
914                 return (1);     /* prefix doesn't match */
915         return (p->pfik_name[n] < '0' || p->pfik_name[n] > '9');
916 }
917
918 /* from pf_print_state.c */
919 int
920 pfi_unmask(void *addr)
921 {
922         struct pf_addr *m = addr;
923         int i = 31, j = 0, b = 0;
924         u_int32_t tmp;
925
926         while (j < 4 && m->addr32[j] == 0xffffffff) {
927                 b += 32;
928                 j++;
929         }
930         if (j < 4) {
931                 tmp = ntohl(m->addr32[j]);
932                 for (i = 31; tmp & (1 << i); --i)
933                         b++;
934         }
935         return (b);
936 }
937
938 void
939 pfi_dohooks(struct pfi_kif *p)
940 {
941         for (; p != NULL; p = p->pfik_parent)
942                 dohooks(p->pfik_ah_head, 0);
943 }
944
945 int
946 pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
947 {
948         if (af == AF_INET) {
949                 switch (dyn->pfid_acnt4) {
950                 case 0:
951                         return (0);
952                 case 1:
953                         return (PF_MATCHA(0, &dyn->pfid_addr4,
954                             &dyn->pfid_mask4, a, AF_INET));
955                 default:
956                         return (pfr_match_addr(dyn->pfid_kt, a, AF_INET));
957                 }
958         } else {
959                 switch (dyn->pfid_acnt6) {
960                 case 0:
961                         return (0);
962                 case 1:
963                         return (PF_MATCHA(0, &dyn->pfid_addr6,
964                             &dyn->pfid_mask6, a, AF_INET6));
965                 default:
966                         return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6));
967                 }
968         }
969 }