xref: /freebsd/sys/netpfil/pf/if_pflog.c (revision 9a405864e0cf7d794ba067fa762b5d3743cd7db5)
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