1d8aa10ccSGleb Smirnoff /*-
26e778a7eSPedro F. Giffuni * SPDX-License-Identifier: ISC
36e778a7eSPedro F. Giffuni *
43b3a8eb9SGleb Smirnoff * The authors of this code are John Ioannidis (ji@tla.org),
53b3a8eb9SGleb Smirnoff * Angelos D. Keromytis (kermit@csd.uch.gr) and
63b3a8eb9SGleb Smirnoff * Niels Provos (provos@physnet.uni-hamburg.de).
73b3a8eb9SGleb Smirnoff *
83b3a8eb9SGleb Smirnoff * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
93b3a8eb9SGleb Smirnoff * in November 1995.
103b3a8eb9SGleb Smirnoff *
113b3a8eb9SGleb Smirnoff * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
123b3a8eb9SGleb Smirnoff * by Angelos D. Keromytis.
133b3a8eb9SGleb Smirnoff *
143b3a8eb9SGleb Smirnoff * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
153b3a8eb9SGleb Smirnoff * and Niels Provos.
163b3a8eb9SGleb Smirnoff *
173b3a8eb9SGleb Smirnoff * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
183b3a8eb9SGleb Smirnoff * and Niels Provos.
193b3a8eb9SGleb Smirnoff * Copyright (c) 2001, Angelos D. Keromytis, Niels Provos.
203b3a8eb9SGleb Smirnoff *
213b3a8eb9SGleb Smirnoff * Permission to use, copy, and modify this software with or without fee
223b3a8eb9SGleb Smirnoff * is hereby granted, provided that this entire notice is included in
233b3a8eb9SGleb Smirnoff * all copies of any software which is or includes a copy or
243b3a8eb9SGleb Smirnoff * modification of this software.
253b3a8eb9SGleb Smirnoff * You may use this code under the GNU public license if you so wish. Please
263b3a8eb9SGleb Smirnoff * contribute changes back to the authors under this freer than GPL license
273b3a8eb9SGleb Smirnoff * so that we may further the use of strong encryption without limitations to
283b3a8eb9SGleb Smirnoff * all.
293b3a8eb9SGleb Smirnoff *
303b3a8eb9SGleb Smirnoff * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
313b3a8eb9SGleb Smirnoff * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
323b3a8eb9SGleb Smirnoff * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
333b3a8eb9SGleb Smirnoff * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
343b3a8eb9SGleb Smirnoff * PURPOSE.
35d8aa10ccSGleb Smirnoff *
36d8aa10ccSGleb Smirnoff * $OpenBSD: if_pflog.c,v 1.26 2007/10/18 21:58:18 mpf Exp $
373b3a8eb9SGleb Smirnoff */
383b3a8eb9SGleb Smirnoff
393b3a8eb9SGleb Smirnoff #include <sys/cdefs.h>
403b3a8eb9SGleb Smirnoff #include "opt_inet.h"
413b3a8eb9SGleb Smirnoff #include "opt_inet6.h"
423b3a8eb9SGleb Smirnoff #include "opt_bpf.h"
433b3a8eb9SGleb Smirnoff #include "opt_pf.h"
443b3a8eb9SGleb Smirnoff
453b3a8eb9SGleb Smirnoff #include <sys/param.h>
463b3a8eb9SGleb Smirnoff #include <sys/kernel.h>
473b3a8eb9SGleb Smirnoff #include <sys/mbuf.h>
483b3a8eb9SGleb Smirnoff #include <sys/module.h>
493b3a8eb9SGleb Smirnoff #include <sys/proc.h>
503b3a8eb9SGleb Smirnoff #include <sys/socket.h>
513b3a8eb9SGleb Smirnoff #include <sys/sockio.h>
523b3a8eb9SGleb Smirnoff
533b3a8eb9SGleb Smirnoff #include <net/bpf.h>
543b3a8eb9SGleb Smirnoff #include <net/if.h>
5576039bc8SGleb Smirnoff #include <net/if_var.h>
563b3a8eb9SGleb Smirnoff #include <net/if_clone.h>
573b3a8eb9SGleb Smirnoff #include <net/if_pflog.h>
583d0d5b21SJustin Hibbits #include <net/if_private.h>
593b3a8eb9SGleb Smirnoff #include <net/if_types.h>
6076039bc8SGleb Smirnoff #include <net/vnet.h>
613b3a8eb9SGleb Smirnoff #include <net/pfvar.h>
623b3a8eb9SGleb Smirnoff
633b3a8eb9SGleb Smirnoff #if defined(INET) || defined(INET6)
643b3a8eb9SGleb Smirnoff #include <netinet/in.h>
653b3a8eb9SGleb Smirnoff #endif
663b3a8eb9SGleb Smirnoff #ifdef INET
673b3a8eb9SGleb Smirnoff #include <netinet/in_var.h>
683b3a8eb9SGleb Smirnoff #include <netinet/ip.h>
693b3a8eb9SGleb Smirnoff #endif
703b3a8eb9SGleb Smirnoff
713b3a8eb9SGleb Smirnoff #ifdef INET6
723b3a8eb9SGleb Smirnoff #include <netinet6/in6_var.h>
733b3a8eb9SGleb Smirnoff #include <netinet6/nd6.h>
743b3a8eb9SGleb Smirnoff #endif /* INET6 */
753b3a8eb9SGleb Smirnoff
763b3a8eb9SGleb Smirnoff #ifdef INET
773b3a8eb9SGleb Smirnoff #include <machine/in_cksum.h>
783b3a8eb9SGleb Smirnoff #endif /* INET */
793b3a8eb9SGleb Smirnoff
803b3a8eb9SGleb Smirnoff #define PFLOGMTU (32768 + MHLEN + MLEN)
813b3a8eb9SGleb Smirnoff
823b3a8eb9SGleb Smirnoff #ifdef PFLOGDEBUG
833b3a8eb9SGleb Smirnoff #define DPRINTF(x) do { if (pflogdebug) printf x ; } while (0)
843b3a8eb9SGleb Smirnoff #else
853b3a8eb9SGleb Smirnoff #define DPRINTF(x)
863b3a8eb9SGleb Smirnoff #endif
873b3a8eb9SGleb Smirnoff
8847e8d432SGleb Smirnoff static int pflogoutput(struct ifnet *, struct mbuf *,
8947e8d432SGleb Smirnoff const struct sockaddr *, struct route *);
903b3a8eb9SGleb Smirnoff static void pflogattach(int);
913b3a8eb9SGleb Smirnoff static int pflogioctl(struct ifnet *, u_long, caddr_t);
923b3a8eb9SGleb Smirnoff static void pflogstart(struct ifnet *);
9391ebcbe0SAlexander V. Chernikov static int pflog_clone_create(struct if_clone *, char *, size_t,
9491ebcbe0SAlexander V. Chernikov struct ifc_data *, struct ifnet **);
9591ebcbe0SAlexander V. Chernikov static int pflog_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
963b3a8eb9SGleb Smirnoff
9742a58907SGleb Smirnoff static const char pflogname[] = "pflog";
983b3a8eb9SGleb Smirnoff
995f901c92SAndrew Turner VNET_DEFINE_STATIC(struct if_clone *, pflog_cloner);
100a0429b54SBjoern A. Zeeb #define V_pflog_cloner VNET(pflog_cloner)
101a0429b54SBjoern A. Zeeb
102a0429b54SBjoern A. Zeeb VNET_DEFINE(struct ifnet *, pflogifs[PFLOGIFS_MAX]); /* for fast access */
103a0429b54SBjoern A. Zeeb #define V_pflogifs VNET(pflogifs)
1043b3a8eb9SGleb Smirnoff
1053b3a8eb9SGleb Smirnoff static void
pflogattach(int npflog __unused)106a0429b54SBjoern A. Zeeb pflogattach(int npflog __unused)
1073b3a8eb9SGleb Smirnoff {
1083b3a8eb9SGleb Smirnoff int i;
10907d138afSZhenlei Huang
1103b3a8eb9SGleb Smirnoff for (i = 0; i < PFLOGIFS_MAX; i++)
111a0429b54SBjoern A. Zeeb V_pflogifs[i] = NULL;
11291ebcbe0SAlexander V. Chernikov
11391ebcbe0SAlexander V. Chernikov struct if_clone_addreq req = {
11491ebcbe0SAlexander V. Chernikov .create_f = pflog_clone_create,
11591ebcbe0SAlexander V. Chernikov .destroy_f = pflog_clone_destroy,
11607d138afSZhenlei Huang .flags = IFC_F_AUTOUNIT | IFC_F_LIMITUNIT,
11707d138afSZhenlei Huang .maxunit = PFLOGIFS_MAX - 1,
11891ebcbe0SAlexander V. Chernikov };
11991ebcbe0SAlexander V. Chernikov V_pflog_cloner = ifc_attach_cloner(pflogname, &req);
12091ebcbe0SAlexander V. Chernikov struct ifc_data ifd = { .unit = 0 };
12191ebcbe0SAlexander V. Chernikov ifc_create_ifp(pflogname, &ifd, NULL);
1223b3a8eb9SGleb Smirnoff }
1233b3a8eb9SGleb Smirnoff
1243b3a8eb9SGleb Smirnoff static int
pflog_clone_create(struct if_clone * ifc,char * name,size_t maxlen,struct ifc_data * ifd,struct ifnet ** ifpp)12591ebcbe0SAlexander V. Chernikov pflog_clone_create(struct if_clone *ifc, char *name, size_t maxlen,
12691ebcbe0SAlexander V. Chernikov struct ifc_data *ifd, struct ifnet **ifpp)
1273b3a8eb9SGleb Smirnoff {
1283b3a8eb9SGleb Smirnoff struct ifnet *ifp;
1293b3a8eb9SGleb Smirnoff
13007d138afSZhenlei Huang MPASS(ifd->unit < PFLOGIFS_MAX);
1313b3a8eb9SGleb Smirnoff
1323b3a8eb9SGleb Smirnoff ifp = if_alloc(IFT_PFLOG);
13391ebcbe0SAlexander V. Chernikov if_initname(ifp, pflogname, ifd->unit);
1343b3a8eb9SGleb Smirnoff ifp->if_mtu = PFLOGMTU;
1353b3a8eb9SGleb Smirnoff ifp->if_ioctl = pflogioctl;
1363b3a8eb9SGleb Smirnoff ifp->if_output = pflogoutput;
1373b3a8eb9SGleb Smirnoff ifp->if_start = pflogstart;
1383b3a8eb9SGleb Smirnoff ifp->if_snd.ifq_maxlen = ifqmaxlen;
1393b3a8eb9SGleb Smirnoff ifp->if_hdrlen = PFLOG_HDRLEN;
1403b3a8eb9SGleb Smirnoff if_attach(ifp);
1413b3a8eb9SGleb Smirnoff
1423b3a8eb9SGleb Smirnoff bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
1433b3a8eb9SGleb Smirnoff
14491ebcbe0SAlexander V. Chernikov V_pflogifs[ifd->unit] = ifp;
14591ebcbe0SAlexander V. Chernikov *ifpp = ifp;
1463b3a8eb9SGleb Smirnoff
1473b3a8eb9SGleb Smirnoff return (0);
1483b3a8eb9SGleb Smirnoff }
1493b3a8eb9SGleb Smirnoff
15091ebcbe0SAlexander V. Chernikov static int
pflog_clone_destroy(struct if_clone * ifc,struct ifnet * ifp,uint32_t flags)15191ebcbe0SAlexander V. Chernikov pflog_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
1523b3a8eb9SGleb Smirnoff {
1533b3a8eb9SGleb Smirnoff int i;
1543b3a8eb9SGleb Smirnoff
15591ebcbe0SAlexander V. Chernikov if (ifp->if_dunit == 0 && (flags & IFC_F_FORCE) == 0)
15691ebcbe0SAlexander V. Chernikov return (EINVAL);
15791ebcbe0SAlexander V. Chernikov
1583b3a8eb9SGleb Smirnoff for (i = 0; i < PFLOGIFS_MAX; i++)
159a0429b54SBjoern A. Zeeb if (V_pflogifs[i] == ifp)
160a0429b54SBjoern A. Zeeb V_pflogifs[i] = NULL;
1613b3a8eb9SGleb Smirnoff
1623b3a8eb9SGleb Smirnoff bpfdetach(ifp);
1633b3a8eb9SGleb Smirnoff if_detach(ifp);
1643b3a8eb9SGleb Smirnoff if_free(ifp);
16591ebcbe0SAlexander V. Chernikov
16691ebcbe0SAlexander V. Chernikov return (0);
1673b3a8eb9SGleb Smirnoff }
1683b3a8eb9SGleb Smirnoff
1693b3a8eb9SGleb Smirnoff /*
1703b3a8eb9SGleb Smirnoff * Start output on the pflog interface.
1713b3a8eb9SGleb Smirnoff */
1723b3a8eb9SGleb Smirnoff static void
pflogstart(struct ifnet * ifp)1733b3a8eb9SGleb Smirnoff pflogstart(struct ifnet *ifp)
1743b3a8eb9SGleb Smirnoff {
1753b3a8eb9SGleb Smirnoff struct mbuf *m;
1763b3a8eb9SGleb Smirnoff
1773b3a8eb9SGleb Smirnoff for (;;) {
1783b3a8eb9SGleb Smirnoff IF_LOCK(&ifp->if_snd);
1793b3a8eb9SGleb Smirnoff _IF_DEQUEUE(&ifp->if_snd, m);
1803b3a8eb9SGleb Smirnoff IF_UNLOCK(&ifp->if_snd);
1813b3a8eb9SGleb Smirnoff
1823b3a8eb9SGleb Smirnoff if (m == NULL)
1833b3a8eb9SGleb Smirnoff return;
1843b3a8eb9SGleb Smirnoff else
1853b3a8eb9SGleb Smirnoff m_freem(m);
1863b3a8eb9SGleb Smirnoff }
1873b3a8eb9SGleb Smirnoff }
1883b3a8eb9SGleb Smirnoff
1893b3a8eb9SGleb Smirnoff static int
pflogoutput(struct ifnet * ifp,struct mbuf * m,const struct sockaddr * dst,struct route * rt)19047e8d432SGleb Smirnoff pflogoutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
1913b3a8eb9SGleb Smirnoff struct route *rt)
1923b3a8eb9SGleb Smirnoff {
1933b3a8eb9SGleb Smirnoff m_freem(m);
1943b3a8eb9SGleb Smirnoff return (0);
1953b3a8eb9SGleb Smirnoff }
1963b3a8eb9SGleb Smirnoff
1973b3a8eb9SGleb Smirnoff /* ARGSUSED */
1983b3a8eb9SGleb Smirnoff static int
pflogioctl(struct ifnet * ifp,u_long cmd,caddr_t data)1993b3a8eb9SGleb Smirnoff pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2003b3a8eb9SGleb Smirnoff {
2013b3a8eb9SGleb Smirnoff switch (cmd) {
2023b3a8eb9SGleb Smirnoff case SIOCSIFFLAGS:
2033b3a8eb9SGleb Smirnoff if (ifp->if_flags & IFF_UP)
2043b3a8eb9SGleb Smirnoff ifp->if_drv_flags |= IFF_DRV_RUNNING;
2053b3a8eb9SGleb Smirnoff else
2063b3a8eb9SGleb Smirnoff ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
2073b3a8eb9SGleb Smirnoff break;
2083b3a8eb9SGleb Smirnoff default:
2093b3a8eb9SGleb Smirnoff return (ENOTTY);
2103b3a8eb9SGleb Smirnoff }
2113b3a8eb9SGleb Smirnoff
2123b3a8eb9SGleb Smirnoff return (0);
2133b3a8eb9SGleb Smirnoff }
2143b3a8eb9SGleb Smirnoff
2153b3a8eb9SGleb Smirnoff static int
pflog_packet(uint8_t action,u_int8_t reason,struct pf_krule * rm,struct pf_krule * am,struct pf_kruleset * ruleset,struct pf_pdesc * pd,int lookupsafe)216*9a405864SKristof Provost pflog_packet(uint8_t action, u_int8_t reason,
217b4a42589SKristof Provost struct pf_krule *rm, struct pf_krule *am,
218e86bddeaSKristof Provost struct pf_kruleset *ruleset, struct pf_pdesc *pd, int lookupsafe)
2193b3a8eb9SGleb Smirnoff {
2203b3a8eb9SGleb Smirnoff struct ifnet *ifn;
2213b3a8eb9SGleb Smirnoff struct pfloghdr hdr;
2223b3a8eb9SGleb Smirnoff
223*9a405864SKristof Provost if (rm == NULL || pd == NULL)
2243b3a8eb9SGleb Smirnoff return (1);
2253b3a8eb9SGleb Smirnoff
226ebc2bab0SZhenlei Huang ifn = V_pflogifs[rm->logif];
227ebc2bab0SZhenlei Huang if (ifn == NULL || !bpf_peers_present(ifn->if_bpf))
2283b3a8eb9SGleb Smirnoff return (0);
2293b3a8eb9SGleb Smirnoff
2303b3a8eb9SGleb Smirnoff bzero(&hdr, sizeof(hdr));
2316d4baa0dSKristof Provost hdr.length = PFLOG_REAL_HDRLEN;
232bc4b0defSKristof Provost hdr.af = pd->af;
233948e8413SKristof Provost hdr.action = action;
2343b3a8eb9SGleb Smirnoff hdr.reason = reason;
235b4a42589SKristof Provost memcpy(hdr.ifname, pd->kif->pfik_name, sizeof(hdr.ifname));
2363b3a8eb9SGleb Smirnoff
2373b3a8eb9SGleb Smirnoff if (am == NULL) {
2383b3a8eb9SGleb Smirnoff hdr.rulenr = htonl(rm->nr);
239c3e14afcSKristof Provost hdr.subrulenr = -1;
2403b3a8eb9SGleb Smirnoff } else {
2413b3a8eb9SGleb Smirnoff hdr.rulenr = htonl(am->nr);
2423b3a8eb9SGleb Smirnoff hdr.subrulenr = htonl(rm->nr);
2433b3a8eb9SGleb Smirnoff if (ruleset != NULL && ruleset->anchor != NULL)
2443b3a8eb9SGleb Smirnoff strlcpy(hdr.ruleset, ruleset->anchor->name,
2453b3a8eb9SGleb Smirnoff sizeof(hdr.ruleset));
2463b3a8eb9SGleb Smirnoff }
24776c5eeccSKristof Provost hdr.ridentifier = htonl(rm->ridentifier);
2483b3a8eb9SGleb Smirnoff /*
2493b3a8eb9SGleb Smirnoff * XXXGL: we avoid pf_socket_lookup() when we are holding
2503b3a8eb9SGleb Smirnoff * state lock, since this leads to unsafe LOR.
2513b3a8eb9SGleb Smirnoff * These conditions are very very rare, however.
2523b3a8eb9SGleb Smirnoff */
2533b3a8eb9SGleb Smirnoff if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done && lookupsafe)
254*9a405864SKristof Provost pd->lookup.done = pf_socket_lookup(pd);
2553b3a8eb9SGleb Smirnoff if (pd->lookup.done > 0)
2563b3a8eb9SGleb Smirnoff hdr.uid = pd->lookup.uid;
2573b3a8eb9SGleb Smirnoff else
2583b3a8eb9SGleb Smirnoff hdr.uid = UID_MAX;
2593b3a8eb9SGleb Smirnoff hdr.pid = NO_PID;
2603b3a8eb9SGleb Smirnoff hdr.rule_uid = rm->cuid;
2613b3a8eb9SGleb Smirnoff hdr.rule_pid = rm->cpid;
262f2064dd1SKajetan Staszkiewicz hdr.dir = pd->dir;
2633b3a8eb9SGleb Smirnoff
2643b3a8eb9SGleb Smirnoff #ifdef INET
265bc4b0defSKristof Provost if (pd->af == AF_INET && pd->dir == PF_OUT) {
2663b3a8eb9SGleb Smirnoff struct ip *ip;
2673b3a8eb9SGleb Smirnoff
268*9a405864SKristof Provost ip = mtod(pd->m, struct ip *);
2693b3a8eb9SGleb Smirnoff ip->ip_sum = 0;
270*9a405864SKristof Provost ip->ip_sum = in_cksum(pd->m, ip->ip_hl << 2);
2713b3a8eb9SGleb Smirnoff }
2723b3a8eb9SGleb Smirnoff #endif /* INET */
2733b3a8eb9SGleb Smirnoff
2742a6009bfSGleb Smirnoff if_inc_counter(ifn, IFCOUNTER_OPACKETS, 1);
275*9a405864SKristof Provost if_inc_counter(ifn, IFCOUNTER_OBYTES, pd->m->m_pkthdr.len);
276*9a405864SKristof Provost bpf_mtap2(ifn->if_bpf, &hdr, PFLOG_HDRLEN, pd->m);
2773b3a8eb9SGleb Smirnoff
2783b3a8eb9SGleb Smirnoff return (0);
2793b3a8eb9SGleb Smirnoff }
2803b3a8eb9SGleb Smirnoff
281a0429b54SBjoern A. Zeeb static void
vnet_pflog_init(const void * unused __unused)282a0429b54SBjoern A. Zeeb vnet_pflog_init(const void *unused __unused)
283a0429b54SBjoern A. Zeeb {
284a0429b54SBjoern A. Zeeb
285a0429b54SBjoern A. Zeeb pflogattach(1);
286a0429b54SBjoern A. Zeeb }
2877d7751a0SBjoern A. Zeeb VNET_SYSINIT(vnet_pflog_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY,
288a0429b54SBjoern A. Zeeb vnet_pflog_init, NULL);
289a0429b54SBjoern A. Zeeb
290a0429b54SBjoern A. Zeeb static void
vnet_pflog_uninit(const void * unused __unused)291a0429b54SBjoern A. Zeeb vnet_pflog_uninit(const void *unused __unused)
292a0429b54SBjoern A. Zeeb {
293a0429b54SBjoern A. Zeeb
29491ebcbe0SAlexander V. Chernikov ifc_detach_cloner(V_pflog_cloner);
295a0429b54SBjoern A. Zeeb }
2967d7751a0SBjoern A. Zeeb /*
2977d7751a0SBjoern A. Zeeb * Detach after pf is gone; otherwise we might touch pflog memory
2987d7751a0SBjoern A. Zeeb * from within pf after freeing pflog.
2997d7751a0SBjoern A. Zeeb */
300a0429b54SBjoern A. Zeeb VNET_SYSUNINIT(vnet_pflog_uninit, SI_SUB_INIT_IF, SI_ORDER_SECOND,
301a0429b54SBjoern A. Zeeb vnet_pflog_uninit, NULL);
302a0429b54SBjoern A. Zeeb
3033b3a8eb9SGleb Smirnoff static int
pflog_modevent(module_t mod,int type,void * data)3043b3a8eb9SGleb Smirnoff pflog_modevent(module_t mod, int type, void *data)
3053b3a8eb9SGleb Smirnoff {
3063b3a8eb9SGleb Smirnoff int error = 0;
3073b3a8eb9SGleb Smirnoff
3083b3a8eb9SGleb Smirnoff switch (type) {
3093b3a8eb9SGleb Smirnoff case MOD_LOAD:
3103b3a8eb9SGleb Smirnoff PF_RULES_WLOCK();
3113b3a8eb9SGleb Smirnoff pflog_packet_ptr = pflog_packet;
3123b3a8eb9SGleb Smirnoff PF_RULES_WUNLOCK();
3133b3a8eb9SGleb Smirnoff break;
3143b3a8eb9SGleb Smirnoff case MOD_UNLOAD:
3153b3a8eb9SGleb Smirnoff PF_RULES_WLOCK();
3163b3a8eb9SGleb Smirnoff pflog_packet_ptr = NULL;
3173b3a8eb9SGleb Smirnoff PF_RULES_WUNLOCK();
3183b3a8eb9SGleb Smirnoff break;
3193b3a8eb9SGleb Smirnoff default:
320a0429b54SBjoern A. Zeeb error = EOPNOTSUPP;
3213b3a8eb9SGleb Smirnoff break;
3223b3a8eb9SGleb Smirnoff }
3233b3a8eb9SGleb Smirnoff
3243b3a8eb9SGleb Smirnoff return error;
3253b3a8eb9SGleb Smirnoff }
3263b3a8eb9SGleb Smirnoff
32742a58907SGleb Smirnoff static moduledata_t pflog_mod = { pflogname, pflog_modevent, 0 };
3283b3a8eb9SGleb Smirnoff
3293b3a8eb9SGleb Smirnoff #define PFLOG_MODVER 1
3303b3a8eb9SGleb Smirnoff
3317d7751a0SBjoern A. Zeeb /* Do not run before pf is initialized as we depend on its locks. */
3327d7751a0SBjoern A. Zeeb DECLARE_MODULE(pflog, pflog_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY);
3333b3a8eb9SGleb Smirnoff MODULE_VERSION(pflog, PFLOG_MODVER);
3343b3a8eb9SGleb Smirnoff MODULE_DEPEND(pflog, pf, PF_MODVER, PF_MODVER, PF_MODVER);
335