svn commit: r302199 - projects/vnet/sys/contrib/ipfilter/netinet

Bjoern A. Zeeb bz at FreeBSD.org
Sat Jun 25 14:14:57 UTC 2016


Author: bz
Date: Sat Jun 25 14:14:55 2016
New Revision: 302199
URL: https://svnweb.freebsd.org/changeset/base/302199

Log:
  A first cut of V_irtualising ipfilter.  Untested.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/vnet/sys/contrib/ipfilter/netinet/ip_fil.h
  projects/vnet/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
  projects/vnet/sys/contrib/ipfilter/netinet/ip_nat.c
  projects/vnet/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c
  projects/vnet/sys/contrib/ipfilter/netinet/ip_rules.c
  projects/vnet/sys/contrib/ipfilter/netinet/mlfk_ipl.c

Modified: projects/vnet/sys/contrib/ipfilter/netinet/ip_fil.h
==============================================================================
--- projects/vnet/sys/contrib/ipfilter/netinet/ip_fil.h	Sat Jun 25 12:54:27 2016	(r302198)
+++ projects/vnet/sys/contrib/ipfilter/netinet/ip_fil.h	Sat Jun 25 14:14:55 2016	(r302199)
@@ -1710,7 +1710,6 @@ typedef struct ipf_main_softc_s {
 
 #ifndef	_KERNEL
 extern	int	ipf_check __P((void *, struct ip *, int, void *, int, mb_t **));
-extern	int	(*ipf_checkp) __P((ip_t *, int, void *, int, mb_t **));
 extern	struct	ifnet *get_unit __P((char *, int));
 extern	char	*get_ifname __P((struct ifnet *));
 extern	int	ipfioctl __P((ipf_main_softc_t *, int, ioctlcmd_t,

Modified: projects/vnet/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
==============================================================================
--- projects/vnet/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c	Sat Jun 25 12:54:27 2016	(r302198)
+++ projects/vnet/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c	Sat Jun 25 14:14:55 2016	(r302199)
@@ -99,31 +99,29 @@ MALLOC_DEFINE(M_IPFILTER, "ipfilter", "I
 # endif
 
 
-static	int	(*ipf_savep) __P((void *, ip_t *, int, void *, int, struct mbuf **));
 static	int	ipf_send_ip __P((fr_info_t *, mb_t *));
 static void	ipf_timer_func __P((void *arg));
-int		ipf_locks_done = 0;
 
-ipf_main_softc_t ipfmain;
+VNET_DEFINE(ipf_main_softc_t, ipfmain);
+#define	V_ipfmain		VNET(ipfmain)
 
 # include <sys/conf.h>
 # if defined(NETBSD_PF)
 #  include <net/pfil.h>
 # endif /* NETBSD_PF */
-/*
- * We provide the ipf_checkp name just to minimize changes later.
- */
-int (*ipf_checkp) __P((void *, ip_t *ip, int hlen, void *ifp, int out, mb_t **mp));
-
 
 static eventhandler_tag ipf_arrivetag, ipf_departtag, ipf_clonetag;
 
-static void ipf_ifevent(void *arg);
+static void ipf_ifevent(void *arg, struct ifnet *ifp);
 
-static void ipf_ifevent(arg)
+static void ipf_ifevent(arg, ifp)
 	void *arg;
+	struct ifnet *ifp;
 {
-        ipf_sync(arg, NULL);
+
+	CURVNET_SET(ifp->if_vnet);
+        ipf_sync(&V_ipfmain, NULL);
+	CURVNET_RESTORE();
 }
 
 
@@ -141,8 +139,10 @@ ipf_check_wrapper(void *arg, struct mbuf
 	ip->ip_len = htons(ip->ip_len);
 	ip->ip_off = htons(ip->ip_off);
 #endif
-	rv = ipf_check(&ipfmain, ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT),
+	CURVNET_SET(ifp->if_vnet);
+	rv = ipf_check(&V_ipfmain, ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT),
 		       mp);
+	CURVNET_RESTORE();
 #if (__FreeBSD_version < 1000019)
 	if ((rv == 0) && (*mp != NULL)) {
 		ip = mtod(*mp, struct ip *);
@@ -159,8 +159,13 @@ ipf_check_wrapper(void *arg, struct mbuf
 static int
 ipf_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
 {
-	return (ipf_check(&ipfmain, mtod(*mp, struct ip *),
-			  sizeof(struct ip6_hdr), ifp, (dir == PFIL_OUT), mp));
+	int error;
+
+	CURVNET_SET(ifp->if_vnet);
+	error = ipf_check(&V_ipfmain, mtod(*mp, struct ip *),
+			  sizeof(struct ip6_hdr), ifp, (dir == PFIL_OUT), mp);
+	CURVNET_RESTORE();
+	return (error);
 }
 # endif
 #if	defined(IPFILTER_LKM)
@@ -221,12 +226,7 @@ ipfattach(softc)
 	}
 
 
-	if (ipf_checkp != ipf_check) {
-		ipf_savep = ipf_checkp;
-		ipf_checkp = ipf_check;
-	}
-
-	bzero((char *)ipfmain.ipf_selwait, sizeof(ipfmain.ipf_selwait));
+	bzero((char *)V_ipfmain.ipf_selwait, sizeof(V_ipfmain.ipf_selwait));
 	softc->ipf_running = 1;
 
 	if (softc->ipf_control_forwarding & 1)
@@ -268,12 +268,6 @@ ipfdetach(softc)
 #endif
 	callout_drain(&softc->ipf_slow_ch);
 
-#ifndef NETBSD_PF
-	if (ipf_checkp != NULL)
-		ipf_checkp = ipf_savep;
-	ipf_savep = NULL;
-#endif
-
 	ipf_fini_all(softc);
 
 	softc->ipf_running = -2;
@@ -304,27 +298,27 @@ ipfioctl(dev, cmd, data, mode
 #if (BSD >= 199306)
         if (securelevel_ge(p->p_cred, 3) && (mode & FWRITE))
 	{
-		ipfmain.ipf_interror = 130001;
+		V_ipfmain.ipf_interror = 130001;
 		return EPERM;
 	}
 #endif
 
 	unit = GET_MINOR(dev);
 	if ((IPL_LOGMAX < unit) || (unit < 0)) {
-		ipfmain.ipf_interror = 130002;
+		V_ipfmain.ipf_interror = 130002;
 		return ENXIO;
 	}
 
-	if (ipfmain.ipf_running <= 0) {
+	if (V_ipfmain.ipf_running <= 0) {
 		if (unit != IPL_LOGIPF && cmd != SIOCIPFINTERROR) {
-			ipfmain.ipf_interror = 130003;
+			V_ipfmain.ipf_interror = 130003;
 			return EIO;
 		}
 		if (cmd != SIOCIPFGETNEXT && cmd != SIOCIPFGET &&
 		    cmd != SIOCIPFSET && cmd != SIOCFRENB &&
 		    cmd != SIOCGETFS && cmd != SIOCGETFF &&
 		    cmd != SIOCIPFINTERROR) {
-			ipfmain.ipf_interror = 130004;
+			V_ipfmain.ipf_interror = 130004;
 			return EIO;
 		}
 	}
@@ -332,7 +326,7 @@ ipfioctl(dev, cmd, data, mode
 	SPL_NET(s);
 
 	CURVNET_SET(TD_TO_VNET(p));
-	error = ipf_ioctlswitch(&ipfmain, unit, data, cmd, mode, p->p_uid, p);
+	error = ipf_ioctlswitch(&V_ipfmain, unit, data, cmd, mode, p->p_uid, p);
 	CURVNET_RESTORE();
 	if (error != -1) {
 		SPL_X(s);
@@ -580,7 +574,7 @@ ipf_send_icmp_err(type, fin, dst)
 			}
 
 		if (dst == 0) {
-			if (ipf_ifpaddr(&ipfmain, 4, FRI_NORMAL, ifp,
+			if (ipf_ifpaddr(&V_ipfmain, 4, FRI_NORMAL, ifp,
 					&dst6, NULL) == -1) {
 				FREE_MB_T(m);
 				return -1;
@@ -617,7 +611,7 @@ ipf_send_icmp_err(type, fin, dst)
 		xtra = MIN(fin->fin_plen, avail - iclen - max_linkhdr);
 		xtra = MIN(xtra, IPV6_MMTU - iclen);
 		if (dst == 0) {
-			if (ipf_ifpaddr(&ipfmain, 6, FRI_NORMAL, ifp,
+			if (ipf_ifpaddr(&V_ipfmain, 6, FRI_NORMAL, ifp,
 					&dst6, NULL) == -1) {
 				FREE_MB_T(m);
 				return -1;
@@ -941,9 +935,9 @@ sendorfree:
     }
 done:
 	if (!error)
-		ipfmain.ipf_frouteok[0]++;
+		V_ipfmain.ipf_frouteok[0]++;
 	else
-		ipfmain.ipf_frouteok[1]++;
+		V_ipfmain.ipf_frouteok[1]++;
 
 	if (has_nhop)
 		fib4_free_nh_ext(fibnum, &nh4);
@@ -1405,13 +1399,13 @@ void
 ipf_event_reg(void)
 {
 	ipf_arrivetag = EVENTHANDLER_REGISTER(ifnet_arrival_event, \
-					       ipf_ifevent, &ipfmain, \
+					       ipf_ifevent, NULL, \
 					       EVENTHANDLER_PRI_ANY);
 	ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \
-					       ipf_ifevent, &ipfmain, \
+					       ipf_ifevent, NULL, \
 					       EVENTHANDLER_PRI_ANY);
 	ipf_clonetag  = EVENTHANDLER_REGISTER(if_clone_event, ipf_ifevent, \
-					       &ipfmain, EVENTHANDLER_PRI_ANY);
+					       NULL, EVENTHANDLER_PRI_ANY);
 }
 
 void

Modified: projects/vnet/sys/contrib/ipfilter/netinet/ip_nat.c
==============================================================================
--- projects/vnet/sys/contrib/ipfilter/netinet/ip_nat.c	Sat Jun 25 12:54:27 2016	(r302198)
+++ projects/vnet/sys/contrib/ipfilter/netinet/ip_nat.c	Sat Jun 25 14:14:55 2016	(r302199)
@@ -133,8 +133,6 @@ static const char rcsid[] = "@(#)$FreeBS
 #define	NBUMPSIDEDF(y,x)do { softn->ipf_nat_stats.ns_side[y].x++; \
 			     DT1(x, fr_info_t *, fin); } while (0)
 
-frentry_t	ipfnatblock;
-
 static ipftuneable_t ipf_nat_tuneables[] = {
 	/* nat */
 	{ { (void *)offsetof(ipf_nat_softc_t, ipf_nat_lock) },
@@ -275,9 +273,6 @@ static	void	ipf_nat_tabmove __P((ipf_nat
 int
 ipf_nat_main_load()
 {
-	bzero((char *)&ipfnatblock, sizeof(ipfnatblock));
-	ipfnatblock.fr_flags = FR_BLOCK|FR_QUICK;
-	ipfnatblock.fr_ref = 1;
 
 	return 0;
 }

Modified: projects/vnet/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c
==============================================================================
--- projects/vnet/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c	Sat Jun 25 12:54:27 2016	(r302198)
+++ projects/vnet/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c	Sat Jun 25 14:14:55 2016	(r302199)
@@ -80,7 +80,9 @@ static void     ipf_p_rpcb_fixlen __P((f
  */
 static	frentry_t	rpcbfr;	/* Skeleton rule for reference by entities
 				   this proxy creates. */
-static	int	rpcbcnt;	/* Upper bound of allocated RPCB sessions. */
+static	VNET_DEFINE(int,	rpcbcnt);
+#define	V_rpcbcnt		VNET(rpcbcnt)
+				/* Upper bound of allocated RPCB sessions. */
 				/* XXX rpcbcnt still requires locking. */
 
 static	int	rpcb_proxy_init = 0;
@@ -107,7 +109,7 @@ static	int	rpcb_proxy_init = 0;
 void
 ipf_p_rpcb_main_load()
 {
-	rpcbcnt = 0;
+	V_rpcbcnt = 0;
 
 	bzero((char *)&rpcbfr, sizeof(rpcbfr));
 	rpcbfr.fr_ref = 1;
@@ -581,7 +583,7 @@ ipf_p_rpcb_insert(rs, rx)
 		return(0);
         }
 
-	if (rpcbcnt == RPCB_MAXREQS)
+	if (V_rpcbcnt == RPCB_MAXREQS)
 		return(-1);
 
 	KMALLOC(rxp, rpcb_xact_t *);
@@ -599,7 +601,7 @@ ipf_p_rpcb_insert(rs, rx)
 
 	rxp->rx_ref = 1;
 
-	++rpcbcnt;
+	++V_rpcbcnt;
 
 	return(0);
 }
@@ -1084,7 +1086,7 @@ ipf_p_rpcb_deref(rs, rx)
 
 	KFREE(rx);
 
-	--rpcbcnt;
+	--V_rpcbcnt;
 }
 
 /* --------------------------------------------------------------------	*/

Modified: projects/vnet/sys/contrib/ipfilter/netinet/ip_rules.c
==============================================================================
--- projects/vnet/sys/contrib/ipfilter/netinet/ip_rules.c	Sat Jun 25 12:54:27 2016	(r302198)
+++ projects/vnet/sys/contrib/ipfilter/netinet/ip_rules.c	Sat Jun 25 14:14:55 2016	(r302199)
@@ -51,7 +51,8 @@
 
 #ifdef IPFILTER_COMPILED
 
-extern ipf_main_softc_t ipfmain;
+VNET_DECLARE(ipf_main_softc_t, ipfmain);
+#define	V_ipfmain		VNET(ipfmain)
 
 
 static u_long in_rule__0[] = {
@@ -129,8 +130,8 @@ int ipfrule_add_out_()
 	fp->fr_dsize = sizeof(ipf_rules_out_[0]);
 	fp->fr_family = AF_INET;
 	fp->fr_func = (ipfunc_t)ipfrule_match_out_;
-	err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,
-			ipfmain.ipf_active, 0);
+	err = frrequest(&V_ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,
+			V_ipfmain.ipf_active, 0);
 	return err;
 }
 
@@ -156,9 +157,9 @@ int ipfrule_remove_out_()
 		}
 	}
 	if (err == 0)
-		err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,
+		err = frrequest(&V_ipfmain, IPL_LOGIPF, SIOCDELFR,
 				(caddr_t)&ipfrule_out_,
-				ipfmain.ipf_active, 0);
+				V_ipfmain.ipf_active, 0);
 	if (err)
 		return err;
 
@@ -198,8 +199,8 @@ int ipfrule_add_in_()
 	fp->fr_dsize = sizeof(ipf_rules_in_[0]);
 	fp->fr_family = AF_INET;
 	fp->fr_func = (ipfunc_t)ipfrule_match_in_;
-	err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,
-			ipfmain.ipf_active, 0);
+	err = frrequest(&V_ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,
+			V_ipfmain.ipf_active, 0);
 	return err;
 }
 
@@ -225,9 +226,9 @@ int ipfrule_remove_in_()
 		}
 	}
 	if (err == 0)
-		err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,
+		err = frrequest(&V_ipfmain, IPL_LOGIPF, SIOCDELFR,
 				(caddr_t)&ipfrule_in_,
-				ipfmain.ipf_active, 0);
+				V_ipfmain.ipf_active, 0);
 	if (err)
 		return err;
 

Modified: projects/vnet/sys/contrib/ipfilter/netinet/mlfk_ipl.c
==============================================================================
--- projects/vnet/sys/contrib/ipfilter/netinet/mlfk_ipl.c	Sat Jun 25 12:54:27 2016	(r302198)
+++ projects/vnet/sys/contrib/ipfilter/netinet/mlfk_ipl.c	Sat Jun 25 14:14:55 2016	(r302199)
@@ -18,6 +18,7 @@
 #include <sys/select.h>
 #if __FreeBSD_version >= 500000
 # include <sys/selinfo.h>
+# include <sys/jail.h>
 #endif
 #include <net/if.h>
 #include <netinet/in_systm.h>
@@ -33,7 +34,8 @@
 #include "netinet/ip_frag.h"
 #include "netinet/ip_sync.h"
 
-extern ipf_main_softc_t ipfmain;
+VNET_DECLARE(ipf_main_softc_t, ipfmain);
+#define	V_ipfmain		VNET(ipfmain)
 
 #if __FreeBSD_version >= 502116
 static struct cdev *ipf_devs[IPL_LOGSIZE];
@@ -70,40 +72,41 @@ static	int	ipfwrite __P((dev_t, struct u
 
 SYSCTL_DECL(_net_inet);
 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
-	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
-		   ptr, val, sysctl_ipf_int, "I", descr);
+	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_VNET|access, \
+		   ptr, val, sysctl_ipf_int, "I", descr)
 #define SYSCTL_DYN_IPF(parent, nbr, name, access,ptr, val, descr) \
-	SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
-	CTLFLAG_DYN|CTLTYPE_INT|access, ptr, val, sysctl_ipf_int, "I", descr)
-static struct sysctl_ctx_list ipf_clist;
+	SYSCTL_ADD_OID(&V_ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
+	CTLFLAG_DYN|CTLTYPE_INT|CTLFLAG_VNET|access, ptr, val, sysctl_ipf_int, "I", descr)
+static VNET_DEFINE(struct sysctl_ctx_list, ipf_clist);
+#define	V_ipf_clist		VNET(ipf_clist)
 #define	CTLFLAG_OFF	0x00800000	/* IPFilter must be disabled */
 #define	CTLFLAG_RWO	(CTLFLAG_RW|CTLFLAG_OFF)
 SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
-SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipfmain.ipf_flags, 0, "IPF flags");
-SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipfmain.ipf_pass, 0, "default pass/block");
-SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipfmain.ipf_active, 0, "IPF is active");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_flags), 0, "IPF flags");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_pass), 0, "default pass/block");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &VNET_NAME(ipfmain.ipf_active), 0, "IPF is active");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO,
-	   &ipfmain.ipf_tcpidletimeout, 0, "TCP idle timeout in seconds");
+	   &VNET_NAME(ipfmain.ipf_tcpidletimeout), 0, "TCP idle timeout in seconds");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO,
-	   &ipfmain.ipf_tcphalfclosed, 0, "timeout for half closed TCP sessions");
+	   &VNET_NAME(ipfmain.ipf_tcphalfclosed), 0, "timeout for half closed TCP sessions");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO,
-	   &ipfmain.ipf_tcpclosewait, 0, "timeout for TCP sessions in closewait status");
+	   &VNET_NAME(ipfmain.ipf_tcpclosewait), 0, "timeout for TCP sessions in closewait status");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO,
-	   &ipfmain.ipf_tcplastack, 0, "timeout for TCP sessions in last ack status");
+	   &VNET_NAME(ipfmain.ipf_tcplastack), 0, "timeout for TCP sessions in last ack status");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO,
-	   &ipfmain.ipf_tcptimeout, 0, "");
+	   &VNET_NAME(ipfmain.ipf_tcptimeout), 0, "");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO,
-	   &ipfmain.ipf_tcpclosed, 0, "");
+	   &VNET_NAME(ipfmain.ipf_tcpclosed), 0, "");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO,
-	   &ipfmain.ipf_udptimeout, 0, "UDP timeout");
+	   &VNET_NAME(ipfmain.ipf_udptimeout), 0, "UDP timeout");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO,
-	   &ipfmain.ipf_udpacktimeout, 0, "");
+	   &VNET_NAME(ipfmain.ipf_udpacktimeout), 0, "");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO,
-	   &ipfmain.ipf_icmptimeout, 0, "ICMP timeout");
+	   &VNET_NAME(ipfmain.ipf_icmptimeout), 0, "ICMP timeout");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
-	   &ipfmain.ipf_running, 0, "IPF is running");
-SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipfmain.ipf_chksrc, 0, "");
-SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipfmain.ipf_minttl, 0, "");
+	   &VNET_NAME(ipfmain.ipf_running), 0, "IPF is running");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_chksrc), 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_minttl), 0, "");
 
 #define CDEV_MAJOR 79
 #include <sys/poll.h>
@@ -178,28 +181,63 @@ ipfilter_modevent(module_t mod, int type
 }
 
 
+static void
+vnet_ipf_init(void)
+{
+	char *defpass;
+	int error;
+
+	if (ipf_create_all(&V_ipfmain) == NULL)
+		return;
+
+	if (ipf_fbsd_sysctl_create(&V_ipfmain) != 0) {
+		ipf_destroy_all(&V_ipfmain);
+		return;
+	}
+
+	error = ipfattach(&V_ipfmain);
+	if (error) {
+		(void)ipf_fbsd_sysctl_destroy(&V_ipfmain);
+		ipf_destroy_all(&V_ipfmain);
+		return;
+	}
+
+	if (FR_ISPASS(V_ipfmain.ipf_pass))
+		defpass = "pass";
+	else if (FR_ISBLOCK(V_ipfmain.ipf_pass))
+		defpass = "block";
+	else
+		defpass = "no-match -> block";
+
+	if (IS_DEFAULT_VNET(curvnet))
+	    printf("%s initialized.  Default = %s all, Logging = %s%s\n",
+		ipfilter_version, defpass,
+#ifdef IPFILTER_LOG
+		"enabled",
+#else
+		"disabled",
+#endif
+#ifdef IPFILTER_COMPILED
+		" (COMPILED)"
+#else
+		""
+#endif
+		);
+}
+VNET_SYSINIT(vnet_ipf_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
+    vnet_ipf_init, NULL);
+
 static int
 ipf_modload()
 {
-	char *defpass, *c, *str;
+	char *c, *str;
 	int i, j, error;
 
 	if (ipf_load_all() != 0)
 		return EIO;
 
-	if (ipf_create_all(&ipfmain) == NULL)
-		return EIO;
-
-	if (ipf_fbsd_sysctl_create(&ipfmain) != 0)
-		return EIO;
-
-	error = ipfattach(&ipfmain);
-	if (error)
-		return error;
-
 	for (i = 0; i < IPL_LOGSIZE; i++)
 		ipf_devs[i] = NULL;
-
 	for (i = 0; (str = ipf_devfiles[i]); i++) {
 		c = NULL;
 		for(j = strlen(str); j > 0; j--)
@@ -217,63 +255,50 @@ ipf_modload()
 		return error;
 	ipf_event_reg();
 
-	if (FR_ISPASS(ipfmain.ipf_pass))
-		defpass = "pass";
-	else if (FR_ISBLOCK(ipfmain.ipf_pass))
-		defpass = "block";
-	else
-		defpass = "no-match -> block";
-
-	printf("%s initialized.  Default = %s all, Logging = %s%s\n",
-		ipfilter_version, defpass,
-#ifdef IPFILTER_LOG
-		"enabled",
-#else
-		"disabled",
-#endif
-#ifdef IPFILTER_COMPILED
-		" (COMPILED)"
-#else
-		""
-#endif
-		);
 	return 0;
 }
 
+static void
+vnet_ipf_uninit(void)
+{
+
+	if (V_ipfmain.ipf_refcnt)
+		return;
+
+	if (ipf_fbsd_sysctl_destroy(&V_ipfmain) != 0)
+		return;
+
+	if (V_ipfmain.ipf_running >= 0) {
+		if (ipfdetach(&V_ipfmain) != 0)
+			return;
+
+		ipf_fbsd_sysctl_destroy(&V_ipfmain);
+		ipf_destroy_all(&V_ipfmain);
+	}
+
+	V_ipfmain.ipf_running = -2;
+}
+VNET_SYSUNINIT(vnet_ipf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
+    vnet_ipf_uninit, NULL);
 
 static int
 ipf_modunload()
 {
 	int error, i;
 
-	if (ipfmain.ipf_refcnt)
-		return EBUSY;
-
-	if (ipf_fbsd_sysctl_destroy(&ipfmain) != 0)
-		return EIO;
+	ipf_event_dereg();
 
 	error = ipf_pfil_unhook();
 	if (error != 0)
 		return error;
 
-	if (ipfmain.ipf_running >= 0) {
-		error = ipfdetach(&ipfmain);
-		if (error != 0)
-			return error;
-
-		ipf_fbsd_sysctl_destroy(&ipfmain);
-		ipf_destroy_all(&ipfmain);
-		ipf_unload_all();
-	} else
-		error = 0;
-
-	ipfmain.ipf_running = -2;
-
 	for (i = 0; ipf_devfiles[i]; i++) {
 		if (ipf_devs[i] != NULL)
 			destroy_dev(ipf_devs[i]);
 	}
 
+	ipf_unload_all();
+
 	printf("%s unloaded\n", ipfilter_version);
 
 	return error;
@@ -287,7 +312,7 @@ static moduledata_t ipfiltermod = {
 };
 
 
-DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY);
+DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND);
 #ifdef	MODULE_VERSION
 MODULE_VERSION(ipfilter, 1);
 #endif
@@ -310,7 +335,7 @@ sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
 	if (!arg1)
 		error = EPERM;
 	else {
-		if ((oidp->oid_kind & CTLFLAG_OFF) && (ipfmain.ipf_running > 0))
+		if ((oidp->oid_kind & CTLFLAG_OFF) && (V_ipfmain.ipf_running > 0))
 			error = EBUSY;
 		else
 			error = SYSCTL_IN(req, arg1, sizeof(int));
@@ -335,24 +360,25 @@ ipfpoll(dev_t dev, int events, struct pr
 
 	revents = 0;
 
+	CURVNET_SET(TD_TO_VNET(td));
 	switch (unit)
 	{
 	case IPL_LOGIPF :
 	case IPL_LOGNAT :
 	case IPL_LOGSTATE :
 #ifdef IPFILTER_LOG
-		if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&ipfmain, unit))
+		if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&V_ipfmain, unit))
 			revents |= events & (POLLIN | POLLRDNORM);
 #endif
 		break;
 	case IPL_LOGAUTH :
-		if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&ipfmain))
+		if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&V_ipfmain))
 			revents |= events & (POLLIN | POLLRDNORM);
 		break;
 	case IPL_LOGSYNC :
-		if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&ipfmain))
+		if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&V_ipfmain))
 			revents |= events & (POLLIN | POLLRDNORM);
-		if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&ipfmain))
+		if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&V_ipfmain))
 			revents |= events & (POLLOUT | POLLWRNORM);
 		break;
 	case IPL_LOGSCAN :
@@ -362,7 +388,8 @@ ipfpoll(dev_t dev, int events, struct pr
 	}
 
 	if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
-		selrecord(td, &ipfmain.ipf_selwait[unit]);
+		selrecord(td, &V_ipfmain.ipf_selwait[unit]);
+	CURVNET_RESTORE();
 
 	return revents;
 }
@@ -465,22 +492,31 @@ static int ipfread(dev, uio)
 #endif
 	struct uio *uio;
 {
+	int error;
 	int	unit = GET_MINOR(dev);
 
 	if (unit < 0)
 		return ENXIO;
 
-	if (ipfmain.ipf_running < 1)
+	CURVNET_SET(CRED_TO_VNET(dev->si_cred));
+	if (V_ipfmain.ipf_running < 1) {
+		CURVNET_RESTORE();
 		return EIO;
+	}
 
-	if (unit == IPL_LOGSYNC)
-		return ipf_sync_read(&ipfmain, uio);
+	if (unit == IPL_LOGSYNC) {
+		error = ipf_sync_read(&V_ipfmain, uio);
+		CURVNET_RESTORE();
+		return error;
+	}
 
 #ifdef IPFILTER_LOG
-	return ipf_log_read(&ipfmain, unit, uio);
+	error = ipf_log_read(&V_ipfmain, unit, uio);
 #else
-	return ENXIO;
+	error = ENXIO;
 #endif
+	CURVNET_RESTORE();
+	return error;
 }
 
 
@@ -503,12 +539,19 @@ static int ipfwrite(dev, uio)
 #endif
 	struct uio *uio;
 {
+	int error;
 
-	if (ipfmain.ipf_running < 1)
+	CURVNET_SET(CRED_TO_VNET(dev->si_cred));
+	if (V_ipfmain.ipf_running < 1) {
+		CURVNET_RESTORE();
 		return EIO;
+	}
 
-	if (GET_MINOR(dev) == IPL_LOGSYNC)
-		return ipf_sync_write(&ipfmain, uio);
+	if (GET_MINOR(dev) == IPL_LOGSYNC) {
+		error = ipf_sync_write(&V_ipfmain, uio);
+		CURVNET_RESTORE();
+		return error;
+	}
 	return ENXIO;
 }
 
@@ -526,7 +569,7 @@ ipf_fbsd_sysctl_create(main_softc)
 	auth_softc = main_softc->ipf_auth_soft;
 	frag_softc = main_softc->ipf_frag_soft;
 
-	sysctl_ctx_init(&ipf_clist);
+	sysctl_ctx_init(&V_ipf_clist);
 
 	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "fr_defnatage", CTLFLAG_RWO,
 	    &nat_softc->ipf_nat_defage, 0, "");
@@ -559,7 +602,7 @@ static int
 ipf_fbsd_sysctl_destroy(main_softc)
 	ipf_main_softc_t *main_softc;
 {
-	if (sysctl_ctx_free(&ipf_clist)) {
+	if (sysctl_ctx_free(&V_ipf_clist)) {
 		printf("sysctl_ctx_free failed");
 		return(ENOTEMPTY);
 	}


More information about the svn-src-projects mailing list