svn commit: r230868 - in stable/9/sys: contrib/pf/net netinet

Gleb Smirnoff glebius at FreeBSD.org
Wed Feb 1 15:57:50 UTC 2012


Author: glebius
Date: Wed Feb  1 15:57:49 2012
New Revision: 230868
URL: http://svn.freebsd.org/changeset/base/230868

Log:
  Merge some cleanups and bugfixes to pfsync(4) and pf(4) from head. Merged
  revisions: r229773,229777,229849-229853,229857,229959,229961-229964,229976.
  
  r229777:
    Merge from OpenBSD:
      revision 1.170
      date: 2011/10/30 23:04:38;  author: mikeb;  state: Exp;  lines: +6 -7
      Allow setting big MTU values on the pfsync interface but not larger
      than the syncdev MTU.  Prompted by the discussion with and tested
      by Maxim Bourmistrov;  ok dlg, mpf
  
    Consistently use sc_ifp->if_mtu in the MTU check throughout the
    module. This backs out r228813.
  
  r229849:
    o Fix panic on module unload, that happened due to mutex being
      destroyed prior to pfsync_uninit(). To do this, move all the
      initialization to the module_t method, instead of SYSINIT(9).
    o Fix another panic after module unload, due to not clearing the
      m_addr_chg_pf_p pointer.
    o Refuse to unload module, unless being unloaded forcibly.
    o Revert the sub argument to MODULE_DECLARE, to the stable/8 value.
  
  r229850:
    Bunch of fixes to pfsync(4) module load/unload:
  
    o Make the pfsync.ko actually usable. Before this change loading it
      didn't register protosw, so was a nop. However, a module /boot/kernel
      did confused users.
    o Rewrite the way we are joining multicast group:
      - Move multicast initialization/destruction to separate functions.
      - Don't allocate memory if we aren't going to join a multicast group.
      - Use modern API for joining/leaving multicast group.
      - Now the utterly wrong pfsync_ifdetach() isn't needed.
    o Move module initialization from SYSINIT(9) to moduledata_t method.
    o Refuse to unload module, unless asked forcibly.
    o Improve a bit some FreeBSD porting code:
      - Use separate malloc type.
      - Simplify swi sheduling.
  
  r229857:
    Can't pass MSIZE to m_cljget(), an mbuf can't be attached as external storage
    to another mbuf.
  
  r229963:
    Add necessary locking in pfsync_in_ureq().
  
  r229976:
    Redo r226660:
     - Define schednetisr() to swi_sched.
     - In the swi handler check if there is some data prepared,
       and if true, then call pfsync_sendout(), however tell it
       not to schedule swi again.
     - Since now we don't obtain the pfsync lock in the swi handler,
       don't use ifqueue mutex to synchronize queue access.
  
  r229773, r229851, r229959, r229961, r229962, r229964 - minor cleanups.

Modified:
  stable/9/sys/contrib/pf/net/if_pfsync.c
  stable/9/sys/contrib/pf/net/pf.c
  stable/9/sys/contrib/pf/net/pf_ioctl.c
  stable/9/sys/contrib/pf/net/pfvar.h
  stable/9/sys/netinet/in_proto.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)

Modified: stable/9/sys/contrib/pf/net/if_pfsync.c
==============================================================================
--- stable/9/sys/contrib/pf/net/if_pfsync.c	Wed Feb  1 15:04:27 2012	(r230867)
+++ stable/9/sys/contrib/pf/net/if_pfsync.c	Wed Feb  1 15:57:49 2012	(r230868)
@@ -47,6 +47,8 @@
  * 1.118, 1.124, 1.148, 1.149, 1.151, 1.171 - fixes to bulk updates
  * 1.120, 1.175 - use monotonic time_uptime
  * 1.122 - reduce number of updates for non-TCP sessions
+ * 1.128 - cleanups
+ * 1.170 - SIOCSIFMTU checks
  */
 
 #ifdef __FreeBSD__
@@ -59,12 +61,6 @@ __FBSDID("$FreeBSD$");
 
 #define	NBPFILTER	1
 
-#ifdef DEV_PFSYNC
-#define	NPFSYNC		DEV_PFSYNC
-#else
-#define	NPFSYNC		0
-#endif
-
 #ifdef DEV_CARP
 #define	NCARP		DEV_CARP
 #else
@@ -92,6 +88,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/taskqueue.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/protosw.h>
 #else
 #include <sys/ioctl.h>
 #include <sys/timeout.h>
@@ -298,19 +295,26 @@ struct pfsync_softc {
 #else
 	struct timeout		 sc_tmo;
 #endif
-#ifdef __FreeBSD__
-	eventhandler_tag	 sc_detachtag;
-#endif
-
 };
 
 #ifdef __FreeBSD__
+static MALLOC_DEFINE(M_PFSYNC, "pfsync", "pfsync data");
 static VNET_DEFINE(struct pfsync_softc	*, pfsyncif) = NULL;
 #define	V_pfsyncif		VNET(pfsyncif)
-
+static VNET_DEFINE(void *, pfsync_swi_cookie) = NULL;
+#define	V_pfsync_swi_cookie	VNET(pfsync_swi_cookie)
 static VNET_DEFINE(struct pfsyncstats, pfsyncstats);
 #define	V_pfsyncstats		VNET(pfsyncstats)
 
+static void	pfsyncintr(void *);
+static int	pfsync_multicast_setup(struct pfsync_softc *);
+static void	pfsync_multicast_cleanup(struct pfsync_softc *);
+static int	pfsync_init(void);
+static void	pfsync_uninit(void);
+static void	pfsync_sendout1(int);
+
+#define	schednetisr(NETISR_PFSYNC)	swi_sched(V_pfsync_swi_cookie, 0)
+
 SYSCTL_NODE(_net, OID_AUTO, pfsync, CTLFLAG_RW, 0, "PFSYNC");
 SYSCTL_VNET_STRUCT(_net_pfsync, OID_AUTO, stats, CTLFLAG_RW,
     &VNET_NAME(pfsyncstats), pfsyncstats,
@@ -321,16 +325,6 @@ struct pfsyncstats	 pfsyncstats;
 #define	V_pfsyncstats	 pfsyncstats
 #endif
 
-#ifdef __FreeBSD__
-static void	pfsyncintr(void *);
-struct pfsync_swi {
-	void *	pfsync_swi_cookie;
-};
-static struct pfsync_swi	 pfsync_swi;
-#define	schednetisr(p)	swi_sched(pfsync_swi.pfsync_swi_cookie, 0)
-#define	NETISR_PFSYNC
-#endif
-
 void	pfsyncattach(int);
 #ifdef __FreeBSD__
 int	pfsync_clone_create(struct if_clone *, int, caddr_t);
@@ -352,7 +346,6 @@ int	pfsyncioctl(struct ifnet *, u_long, 
 void	pfsyncstart(struct ifnet *);
 
 struct mbuf *pfsync_if_dequeue(struct ifnet *);
-struct mbuf *pfsync_get_mbuf(struct pfsync_softc *);
 
 void	pfsync_deferred(struct pf_state *, int);
 void	pfsync_undefer(struct pfsync_deferral *, int);
@@ -364,11 +357,8 @@ void	pfsync_update_state_req(struct pf_s
 void	pfsync_drop(struct pfsync_softc *);
 void	pfsync_sendout(void);
 void	pfsync_send_plus(void *, size_t);
-int	pfsync_tdb_sendout(struct pfsync_softc *);
-int	pfsync_sendout_mbuf(struct pfsync_softc *, struct mbuf *);
 void	pfsync_timeout(void *);
 void	pfsync_tdb_timeout(void *);
-void	pfsync_send_bus(struct pfsync_softc *, u_int8_t);
 
 void	pfsync_bulk_start(void);
 void	pfsync_bulk_status(u_int8_t);
@@ -376,8 +366,6 @@ void	pfsync_bulk_update(void *);
 void	pfsync_bulk_fail(void *);
 
 #ifdef __FreeBSD__
-void	pfsync_ifdetach(void *, struct ifnet *);
-
 /* XXX: ugly */
 #define	betoh64		(unsigned long long)be64toh
 #define	timeout_del	callout_stop
@@ -389,6 +377,10 @@ int	pfsync_sync_ok;
 #endif
 
 #ifdef __FreeBSD__
+VNET_DEFINE(struct ifc_simple_data, pfsync_cloner_data);
+VNET_DEFINE(struct if_clone, pfsync_cloner);
+#define	V_pfsync_cloner_data	VNET(pfsync_cloner_data)
+#define	V_pfsync_cloner		VNET(pfsync_cloner)
 IFC_SIMPLE_DECLARE(pfsync, 1);
 #else
 struct if_clone	pfsync_cloner =
@@ -414,25 +406,20 @@ pfsync_clone_create(struct if_clone *ifc
 	if (unit != 0)
 		return (EINVAL);
 
-#ifndef __FreeBSD__
+#ifdef __FreeBSD__
+	sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
+	sc->pfsync_sync_ok = 1;
+#else
 	pfsync_sync_ok = 1;
+	sc = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT | M_ZERO);
 #endif
 
-	sc = malloc(sizeof(struct pfsync_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
-	if (sc == NULL)
-		return (ENOMEM);
-
 	for (q = 0; q < PFSYNC_S_COUNT; q++)
 		TAILQ_INIT(&sc->sc_qs[q]);
 
 #ifdef __FreeBSD__
-	sc->pfsync_sync_ok = 1;
-	sc->sc_pool = uma_zcreate("pfsync", PFSYNC_PLSIZE,
-			NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
-	if (sc->sc_pool == NULL) {
-		free(sc, M_DEVBUF);
-		return (ENOMEM);
-	}
+	sc->sc_pool = uma_zcreate("pfsync", PFSYNC_PLSIZE, NULL, NULL, NULL,
+	    NULL, UMA_ALIGN_PTR, 0);
 #else
 	pool_init(&sc->sc_pool, PFSYNC_PLSIZE, 0, 0, 0, "pfsync", NULL);
 #endif
@@ -445,13 +432,7 @@ pfsync_clone_create(struct if_clone *ifc
 	sc->sc_len = PFSYNC_MINPKT;
 	sc->sc_maxupdates = 128;
 
-#ifdef __FreeBSD__
-	sc->sc_imo.imo_membership = (struct in_multi **)malloc(
-	    (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_DEVBUF,
-	    M_NOWAIT | M_ZERO);
-	sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
-	sc->sc_imo.imo_multicast_vif = -1;
-#else
+#ifndef __FreeBSD__
 	sc->sc_imo.imo_membership = (struct in_multi **)malloc(
 	    (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
 	    M_WAITOK | M_ZERO);
@@ -461,26 +442,11 @@ pfsync_clone_create(struct if_clone *ifc
 #ifdef __FreeBSD__
 	ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
 	if (ifp == NULL) {
-		free(sc->sc_imo.imo_membership, M_DEVBUF);
 		uma_zdestroy(sc->sc_pool);
-		free(sc, M_DEVBUF);
+		free(sc, M_PFSYNC);
 		return (ENOSPC);
 	}
 	if_initname(ifp, ifc->ifc_name, unit);
-
-	sc->sc_detachtag = EVENTHANDLER_REGISTER(ifnet_departure_event,
-#ifdef __FreeBSD__
-	    pfsync_ifdetach, V_pfsyncif, EVENTHANDLER_PRI_ANY);
-#else
-	    pfsync_ifdetach, pfsyncif, EVENTHANDLER_PRI_ANY);
-#endif
-	if (sc->sc_detachtag == NULL) {
-		if_free(ifp);
-		free(sc->sc_imo.imo_membership, M_DEVBUF);
-		uma_zdestroy(sc->sc_pool);
-		free(sc, M_DEVBUF);
-		return (ENOSPC);
-	}
 #else
 	ifp = &sc->sc_if;
 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
@@ -492,13 +458,12 @@ pfsync_clone_create(struct if_clone *ifc
 	ifp->if_type = IFT_PFSYNC;
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
 	ifp->if_hdrlen = sizeof(struct pfsync_header);
-	ifp->if_mtu = 1500; /* XXX */
+	ifp->if_mtu = ETHERMTU;
 #ifdef __FreeBSD__
 	callout_init(&sc->sc_tmo, CALLOUT_MPSAFE);
 	callout_init_mtx(&sc->sc_bulk_tmo, &pf_task_mtx, 0);
 	callout_init(&sc->sc_bulkfail_tmo, CALLOUT_MPSAFE);
 #else
-	ifp->if_hardmtu = MCLBYTES; /* XXX */
 	timeout_set(&sc->sc_tmo, pfsync_timeout, sc);
 	timeout_set(&sc->sc_bulk_tmo, pfsync_bulk_update, sc);
 	timeout_set(&sc->sc_bulkfail_tmo, pfsync_bulk_fail, sc);
@@ -540,7 +505,6 @@ pfsync_clone_destroy(struct ifnet *ifp)
 	struct pfsync_softc *sc = ifp->if_softc;
 
 #ifdef __FreeBSD__
-	EVENTHANDLER_DEREGISTER(ifnet_departure_event, sc->sc_detachtag);
 	PF_LOCK();
 #endif
 	timeout_del(&sc->sc_bulkfail_tmo);
@@ -576,11 +540,13 @@ pfsync_clone_destroy(struct ifnet *ifp)
 #endif
 #ifdef __FreeBSD__
 	if_free(ifp);
-	free(sc->sc_imo.imo_membership, M_DEVBUF);
+	if (sc->sc_imo.imo_membership)
+		pfsync_multicast_cleanup(sc);
+	free(sc, M_PFSYNC);
 #else
 	free(sc->sc_imo.imo_membership, M_IPMOPTS);
-#endif
 	free(sc, M_DEVBUF);
+#endif
 
 #ifdef __FreeBSD__
 	V_pfsyncif = NULL;
@@ -721,9 +687,9 @@ pfsync_state_import(struct pfsync_state 
 	int pool_flags;
 	int error;
 
+#ifdef __FreeBSD__
 	PF_LOCK_ASSERT();
 
-#ifdef __FreeBSD__
 	if (sp->creatorid == 0 && V_pf_status.debug >= PF_DEBUG_MISC) {
 #else
 	if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) {
@@ -863,11 +829,7 @@ pfsync_state_import(struct pfsync_state 
 		CLR(st->state_flags, PFSTATE_NOSYNC);
 		if (ISSET(st->state_flags, PFSTATE_ACK)) {
 			pfsync_q_ins(st, PFSYNC_S_IACK);
-#ifdef __FreeBSD__
-			pfsync_sendout();
-#else
 			schednetisr(NETISR_PFSYNC);
-#endif
 		}
 	}
 	CLR(st->state_flags, PFSTATE_ACK);
@@ -1323,11 +1285,7 @@ pfsync_in_upd(struct pfsync_pkt *pkt, st
 			V_pfsyncstats.pfsyncs_stale++;
 
 			pfsync_update_state(st);
-#ifdef __FreeBSD__
-			pfsync_sendout();
-#else
 			schednetisr(NETISR_PFSYNC);
-#endif
 			continue;
 		}
 		pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
@@ -1433,11 +1391,7 @@ pfsync_in_upd_c(struct pfsync_pkt *pkt, 
 			V_pfsyncstats.pfsyncs_stale++;
 
 			pfsync_update_state(st);
-#ifdef __FreeBSD__
-			pfsync_sendout();
-#else
 			schednetisr(NETISR_PFSYNC);
-#endif
 			continue;
 		}
 		pfsync_alloc_scrub_memory(&up->dst, &st->dst);
@@ -1473,6 +1427,9 @@ pfsync_in_ureq(struct pfsync_pkt *pkt, s
 	}
 	ura = (struct pfsync_upd_req *)(mp->m_data + offp);
 
+#ifdef __FreeBSD__
+	PF_LOCK();
+#endif
 	for (i = 0; i < count; i++) {
 		ur = &ura[i];
 
@@ -1490,11 +1447,12 @@ pfsync_in_ureq(struct pfsync_pkt *pkt, s
 			if (ISSET(st->state_flags, PFSTATE_NOSYNC))
 				continue;
 
-			PF_LOCK();
 			pfsync_update_state_req(st);
-			PF_UNLOCK();
 		}
 	}
+#ifdef __FreeBSD__
+	PF_UNLOCK();
+#endif
 
 	return (len);
 }
@@ -1617,7 +1575,7 @@ pfsync_in_bus(struct pfsync_pkt *pkt, st
 #ifdef __FreeBSD__
 		callout_reset(&sc->sc_bulkfail_tmo, 4 * hz +
 		    V_pf_pool_limits[PF_LIMIT_STATES].limit /
-		    ((sc->sc_sync_if->if_mtu - PFSYNC_MINPKT) /
+		    ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) /
 		    sizeof(struct pfsync_state)),
 		    pfsync_bulk_fail, V_pfsyncif);
 #else
@@ -1827,10 +1785,10 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
 #endif
 		break;
 	case SIOCSIFMTU:
-		if (ifr->ifr_mtu <= PFSYNC_MINPKT)
+		if (!sc->sc_sync_if ||
+		    ifr->ifr_mtu <= PFSYNC_MINPKT ||
+		    ifr->ifr_mtu > sc->sc_sync_if->if_mtu)
 			return (EINVAL);
-		if (ifr->ifr_mtu > MCLBYTES) /* XXX could be bigger */
-			ifr->ifr_mtu = MCLBYTES;
 		if (ifr->ifr_mtu < ifp->if_mtu) {
 			s = splnet();
 #ifdef __FreeBSD__
@@ -1892,12 +1850,15 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
 			sc->sc_sync_if = NULL;
 #ifdef __FreeBSD__
 			PF_UNLOCK();
-#endif
+			if (imo->imo_membership)
+				pfsync_multicast_cleanup(sc);
+#else
 			if (imo->imo_num_memberships > 0) {
 				in_delmulti(imo->imo_membership[
 				    --imo->imo_num_memberships]);
 				imo->imo_multicast_ifp = NULL;
 			}
+#endif
 			break;
 		}
 
@@ -1922,57 +1883,53 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
 			pfsync_sendout();
 		sc->sc_sync_if = sifp;
 
-		if (imo->imo_num_memberships > 0) {
 #ifdef __FreeBSD__
+		if (imo->imo_membership) {
 			PF_UNLOCK();
-#endif
-			in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
-#ifdef __FreeBSD__
+			pfsync_multicast_cleanup(sc);
 			PF_LOCK();
-#endif
+		}
+#else
+		if (imo->imo_num_memberships > 0) {
+			in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
 			imo->imo_multicast_ifp = NULL;
 		}
+#endif
 
-		if (sc->sc_sync_if &&
 #ifdef __FreeBSD__
+		if (sc->sc_sync_if &&
 		    sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) {
+			PF_UNLOCK();
+			error = pfsync_multicast_setup(sc);
+			if (error)
+				return (error);
+			PF_LOCK();
+		}
 #else
+		if (sc->sc_sync_if &&
 		    sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
-#endif
 			struct in_addr addr;
 
 			if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
 				sc->sc_sync_if = NULL;
-#ifdef __FreeBSD__
-				PF_UNLOCK();
-#endif
 				splx(s);
 				return (EADDRNOTAVAIL);
 			}
 
-#ifdef __FreeBSD__
-			addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
-#else
 			addr.s_addr = INADDR_PFSYNC_GROUP;
-#endif
 
-#ifdef __FreeBSD__
-			PF_UNLOCK();
-#endif
 			if ((imo->imo_membership[0] =
 			    in_addmulti(&addr, sc->sc_sync_if)) == NULL) {
 				sc->sc_sync_if = NULL;
 				splx(s);
 				return (ENOBUFS);
 			}
-#ifdef __FreeBSD__
-			PF_LOCK();
-#endif
 			imo->imo_num_memberships++;
 			imo->imo_multicast_ifp = sc->sc_sync_if;
 			imo->imo_multicast_ttl = PFSYNC_DFLTTL;
 			imo->imo_multicast_loop = 0;
 		}
+#endif	/* !__FreeBSD__ */
 
 		ip = &sc->sc_template;
 		bzero(ip, sizeof(*ip));
@@ -2111,7 +2068,7 @@ pfsync_drop(struct pfsync_softc *sc)
 #ifdef PFSYNC_DEBUG
 #ifdef __FreeBSD__
 			KASSERT(st->sync_state == q,
-				("%s: st->sync_state == q", 
+				("%s: st->sync_state == q",
 					__FUNCTION__));
 #else
 			KASSERT(st->sync_state == q);
@@ -2141,12 +2098,20 @@ pfsync_drop(struct pfsync_softc *sc)
 	sc->sc_len = PFSYNC_MINPKT;
 }
 
-void
-pfsync_sendout(void)
-{
 #ifdef __FreeBSD__
+void pfsync_sendout()
+{
+	pfsync_sendout1(1);
+}
+
+static void
+pfsync_sendout1(int schedswi)
+{
 	struct pfsync_softc *sc = V_pfsyncif;
 #else
+void
+pfsync_sendout(void)
+{
 	struct pfsync_softc *sc = pfsyncif;
 #endif
 #if NBPFILTER > 0
@@ -2167,7 +2132,6 @@ pfsync_sendout(void)
 #endif
 #ifdef __FreeBSD__
 	size_t pktlen;
-	int dummy_error;
 #endif
 	int offset;
 	int q, count = 0;
@@ -2207,8 +2171,7 @@ pfsync_sendout(void)
 	if (pktlen > MHLEN) {
 		/* Find the right pool to allocate from. */
 		/* XXX: This is ugly. */
-		m_cljget(m, M_DONTWAIT, pktlen <= MSIZE ? MSIZE :
-			pktlen <= MCLBYTES ? MCLBYTES :
+		m_cljget(m, M_DONTWAIT, pktlen <= MCLBYTES ? MCLBYTES :
 #if MJUMPAGESIZE != MCLBYTES
 			pktlen <= MJUMPAGESIZE ? MJUMPAGESIZE :
 #endif
@@ -2373,8 +2336,14 @@ pfsync_sendout(void)
 	sc->sc_ifp->if_obytes += m->m_pkthdr.len;
 	sc->sc_len = PFSYNC_MINPKT;
 
-	IFQ_ENQUEUE(&sc->sc_ifp->if_snd, m, dummy_error);
-	schednetisr(NETISR_PFSYNC);
+	if (!_IF_QFULL(&sc->sc_ifp->if_snd))
+		_IF_ENQUEUE(&sc->sc_ifp->if_snd, m);
+	else {
+		m_freem(m);
+                sc->sc_ifp->if_snd.ifq_drops++;
+	}
+	if (schedswi)
+		swi_sched(V_pfsync_swi_cookie, 0);
 #else
 	sc->sc_if.if_opackets++;
 	sc->sc_if.if_obytes += m->m_pkthdr.len;
@@ -2433,11 +2402,7 @@ pfsync_insert_state(struct pf_state *st)
 	pfsync_q_ins(st, PFSYNC_S_INS);
 
 	if (ISSET(st->state_flags, PFSTATE_ACK))
-#ifdef __FreeBSD__
-		pfsync_sendout();
-#else
 		schednetisr(NETISR_PFSYNC);
-#endif
 	else
 		st->sync_updates = 0;
 }
@@ -2636,11 +2601,7 @@ pfsync_update_state(struct pf_state *st)
 
 	if (sync || (time_uptime - st->pfsync_time) < 2) {
 		pfsync_upds++;
-#ifdef __FreeBSD__
-		pfsync_sendout();
-#else
 		schednetisr(NETISR_PFSYNC);
-#endif
 	}
 }
 
@@ -2676,7 +2637,7 @@ pfsync_request_update(u_int32_t creatori
 		nlen += sizeof(struct pfsync_subheader);
 
 #ifdef __FreeBSD__
-	if (sc->sc_len + nlen > sc->sc_sync_if->if_mtu) {
+	if (sc->sc_len + nlen > sc->sc_ifp->if_mtu) {
 #else
 	if (sc->sc_len + nlen > sc->sc_if.if_mtu) {
 #endif
@@ -2691,11 +2652,7 @@ pfsync_request_update(u_int32_t creatori
 	TAILQ_INSERT_TAIL(&sc->sc_upd_req_list, item, ur_entry);
 	sc->sc_len += nlen;
 
-#ifdef __FreeBSD__
-	pfsync_sendout();
-#else
 	schednetisr(NETISR_PFSYNC);
-#endif
 }
 
 void
@@ -2724,11 +2681,7 @@ pfsync_update_state_req(struct pf_state 
 		pfsync_q_del(st);
 	case PFSYNC_S_NONE:
 		pfsync_q_ins(st, PFSYNC_S_UPD);
-#ifdef __FreeBSD__
-		pfsync_sendout();
-#else
 		schednetisr(NETISR_PFSYNC);
-#endif
 		return;
 
 	case PFSYNC_S_INS:
@@ -2892,7 +2845,7 @@ pfsync_q_del(struct pf_state *st)
 	int q = st->sync_state;
 
 #ifdef __FreeBSD__
-	KASSERT(st->sync_state != PFSYNC_S_NONE, 
+	KASSERT(st->sync_state != PFSYNC_S_NONE,
 		("%s: st->sync_state != PFSYNC_S_NONE", __FUNCTION__));
 #else
 	KASSERT(st->sync_state != PFSYNC_S_NONE);
@@ -3023,7 +2976,7 @@ pfsync_bulk_start(void)
 		printf("pfsync: received bulk update request\n");
 
 #ifdef __FreeBSD__
-	PF_LOCK();
+	PF_LOCK_ASSERT();
 	if (TAILQ_EMPTY(&V_state_list))
 #else
 	if (TAILQ_EMPTY(&state_list))
@@ -3037,15 +2990,11 @@ pfsync_bulk_start(void)
 #else
 			sc->sc_bulk_next = TAILQ_FIRST(&state_list);
 #endif
-			sc->sc_bulk_last = sc->sc_bulk_next;
+		sc->sc_bulk_last = sc->sc_bulk_next;
 
-			pfsync_bulk_status(PFSYNC_BUS_START);
-			callout_reset(&sc->sc_bulk_tmo, 1,
-			    pfsync_bulk_update, sc);
+		pfsync_bulk_status(PFSYNC_BUS_START);
+		callout_reset(&sc->sc_bulk_tmo, 1, pfsync_bulk_update, sc);
 	}
-#ifdef __FreeBSD__
-	PF_UNLOCK();
-#endif
 }
 
 void
@@ -3306,7 +3255,11 @@ pfsyncintr(void *arg)
 	CURVNET_SET(sc->sc_ifp->if_vnet);
 	pfsync_ints++;
 
-	IF_DEQUEUE_ALL(&sc->sc_ifp->if_snd, m);
+	PF_LOCK();
+	if (sc->sc_len > PFSYNC_MINPKT)
+		pfsync_sendout1(0);
+	_IF_DEQUEUE_ALL(&sc->sc_ifp->if_snd, m);
+	PF_UNLOCK();
 
 	for (; m != NULL; m = n) {
 
@@ -3355,54 +3308,91 @@ pfsync_sysctl(int *name, u_int namelen, 
 }
 
 #ifdef __FreeBSD__
-void
-pfsync_ifdetach(void *arg, struct ifnet *ifp)
+static int
+pfsync_multicast_setup(struct pfsync_softc *sc)
 {
-	struct pfsync_softc *sc = (struct pfsync_softc *)arg;
-	struct ip_moptions *imo;
-
-	if (sc == NULL || sc->sc_sync_if != ifp)
-		return;         /* not for us; unlocked read */
+	struct ip_moptions *imo = &sc->sc_imo;
+	int error;
 
-	CURVNET_SET(sc->sc_ifp->if_vnet);
+	if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
+		sc->sc_sync_if = NULL;
+		return (EADDRNOTAVAIL);
+	}
 
-	PF_LOCK();
+	imo->imo_membership = (struct in_multi **)malloc(
+	    (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_PFSYNC,
+	    M_WAITOK | M_ZERO);
+	imo->imo_max_memberships = IP_MIN_MEMBERSHIPS;
+	imo->imo_multicast_vif = -1;
 
-	/* Deal with a member interface going away from under us. */
-	sc->sc_sync_if = NULL;
-	imo = &sc->sc_imo;
-	if (imo->imo_num_memberships > 0) {
-		KASSERT(imo->imo_num_memberships == 1,
-		    ("%s: imo_num_memberships != 1", __func__));
-		/*
-		 * Our event handler is always called after protocol
-		 * domains have been detached from the underlying ifnet.
-		 * Do not call in_delmulti(); we held a single reference
-		 * which the protocol domain has purged in in_purgemaddrs().
-		 */
-		PF_UNLOCK();
-		imo->imo_membership[--imo->imo_num_memberships] = NULL;
-		PF_LOCK();
-		imo->imo_multicast_ifp = NULL;
-	}
+	if ((error = in_joingroup(sc->sc_sync_if, &sc->sc_sync_peer, NULL,
+	    &imo->imo_membership[0])) != 0) {
+		free(imo->imo_membership, M_PFSYNC);
+		return (error);
+	}
+	imo->imo_num_memberships++;
+	imo->imo_multicast_ifp = sc->sc_sync_if;
+	imo->imo_multicast_ttl = PFSYNC_DFLTTL;
+	imo->imo_multicast_loop = 0;
 
-	PF_UNLOCK();
-	
-	CURVNET_RESTORE();
+	return (0);
 }
 
+static void
+pfsync_multicast_cleanup(struct pfsync_softc *sc)
+{
+	struct ip_moptions *imo = &sc->sc_imo;
+
+	in_leavegroup(imo->imo_membership[0], NULL);
+	free(imo->imo_membership, M_PFSYNC);
+	imo->imo_membership = NULL;
+	imo->imo_multicast_ifp = NULL;
+}
+
+#ifdef INET
+extern  struct domain inetdomain;
+static struct protosw in_pfsync_protosw = {
+	.pr_type =		SOCK_RAW,
+	.pr_domain =		&inetdomain,
+	.pr_protocol =		IPPROTO_PFSYNC,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
+	.pr_input =		pfsync_input,
+	.pr_output =		(pr_output_t *)rip_output,
+	.pr_ctloutput =		rip_ctloutput,
+	.pr_usrreqs =		&rip_usrreqs
+};
+#endif
+
 static int
-vnet_pfsync_init(const void *unused)
+pfsync_init()
 {
+	VNET_ITERATOR_DECL(vnet_iter);
 	int error = 0;
 
-	pfsyncattach(0);
-
-	error = swi_add(NULL, "pfsync", pfsyncintr, V_pfsyncif,
-		SWI_NET, INTR_MPSAFE, &pfsync_swi.pfsync_swi_cookie);
+	VNET_LIST_RLOCK();
+	VNET_FOREACH(vnet_iter) {
+		CURVNET_SET(vnet_iter);
+		V_pfsync_cloner = pfsync_cloner;
+		V_pfsync_cloner_data = pfsync_cloner_data;
+		V_pfsync_cloner.ifc_data = &V_pfsync_cloner_data;
+		if_clone_attach(&V_pfsync_cloner);
+		error = swi_add(NULL, "pfsync", pfsyncintr, V_pfsyncif,
+		    SWI_NET, INTR_MPSAFE, &V_pfsync_swi_cookie);
+		CURVNET_RESTORE();
+		if (error)
+			goto fail_locked;
+	}
+	VNET_LIST_RUNLOCK();
+#ifdef INET
+	error = pf_proto_register(PF_INET, &in_pfsync_protosw);
 	if (error)
-		panic("%s: swi_add %d", __func__, error);
-
+		goto fail;
+	error = ipproto_register(IPPROTO_PFSYNC);
+	if (error) {
+		pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
+		goto fail;
+	}
+#endif
 	PF_LOCK();
 	pfsync_state_import_ptr = pfsync_state_import;
 	pfsync_up_ptr = pfsync_up;
@@ -3415,13 +3405,27 @@ vnet_pfsync_init(const void *unused)
 	PF_UNLOCK();
 
 	return (0);
+
+fail:
+	VNET_LIST_RLOCK();
+fail_locked:
+	VNET_FOREACH(vnet_iter) {
+		CURVNET_SET(vnet_iter);
+		if (V_pfsync_swi_cookie) {
+			swi_remove(V_pfsync_swi_cookie);
+			if_clone_detach(&V_pfsync_cloner);
+		}
+		CURVNET_RESTORE();
+	}
+	VNET_LIST_RUNLOCK();
+
+	return (error);
 }
 
-static int
-vnet_pfsync_uninit(const void *unused)
+static void
+pfsync_uninit()
 {
-
-	swi_remove(pfsync_swi.pfsync_swi_cookie);
+	VNET_ITERATOR_DECL(vnet_iter);
 
 	PF_LOCK();
 	pfsync_state_import_ptr = NULL;
@@ -3434,30 +3438,18 @@ vnet_pfsync_uninit(const void *unused)
 	pfsync_defer_ptr = NULL;
 	PF_UNLOCK();
 
-	if_clone_detach(&pfsync_cloner);
-
-	return (0);
+	ipproto_unregister(IPPROTO_PFSYNC);
+	pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
+	VNET_LIST_RLOCK();
+	VNET_FOREACH(vnet_iter) {
+		CURVNET_SET(vnet_iter);
+		swi_remove(V_pfsync_swi_cookie);
+		if_clone_detach(&V_pfsync_cloner);
+		CURVNET_RESTORE();
+	}
+	VNET_LIST_RUNLOCK();
 }
 
-/* Define startup order. */
-#define	PFSYNC_SYSINIT_ORDER	SI_SUB_PROTO_IF
-#define	PFSYNC_MODEVENT_ORDER	(SI_ORDER_FIRST) /* On boot slot in here. */
-#define	PFSYNC_VNET_ORDER	(PFSYNC_MODEVENT_ORDER + 2) /* Later still. */
-
-/*
- * Starting up.
- * VNET_SYSINIT is called for each existing vnet and each new vnet.
- */
-VNET_SYSINIT(vnet_pfsync_init, PFSYNC_SYSINIT_ORDER, PFSYNC_VNET_ORDER,
-    vnet_pfsync_init, NULL);
-
-/*
- * Closing up shop. These are done in REVERSE ORDER,
- * Not called on reboot.
- * VNET_SYSUNINIT is called for each exiting vnet as it exits.
- */
-VNET_SYSUNINIT(vnet_pfsync_uninit, PFSYNC_SYSINIT_ORDER, PFSYNC_VNET_ORDER,
-    vnet_pfsync_uninit, NULL);
 static int
 pfsync_modevent(module_t mod, int type, void *data)
 {
@@ -3465,21 +3457,23 @@ pfsync_modevent(module_t mod, int type, 
 
 	switch (type) {
 	case MOD_LOAD:
-#ifndef __FreeBSD__
-		pfsyncattach(0);
-#endif
+		error = pfsync_init();
+		break;
+	case MOD_QUIESCE:
+		/*
+		 * Module should not be unloaded due to race conditions.
+		 */
+		error = EPERM;
 		break;
 	case MOD_UNLOAD:
-#ifndef __FreeBSD__
-		if_clone_detach(&pfsync_cloner);
-#endif
+		pfsync_uninit();
 		break;
 	default:
 		error = EINVAL;
 		break;
 	}
 
-	return error;
+	return (error);
 }
 
 static moduledata_t pfsync_mod = {
@@ -3490,7 +3484,7 @@ static moduledata_t pfsync_mod = {
 
 #define PFSYNC_MODVER 1
 
-DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
 MODULE_VERSION(pfsync, PFSYNC_MODVER);
 MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER);
 #endif /* __FreeBSD__ */

Modified: stable/9/sys/contrib/pf/net/pf.c
==============================================================================
--- stable/9/sys/contrib/pf/net/pf.c	Wed Feb  1 15:04:27 2012	(r230867)
+++ stable/9/sys/contrib/pf/net/pf.c	Wed Feb  1 15:57:49 2012	(r230868)
@@ -47,23 +47,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_bpf.h"
 #include "opt_pf.h"
 
-#ifdef DEV_BPF
-#define	NBPFILTER	DEV_BPF
-#else
-#define	NBPFILTER	0
-#endif
-
-#ifdef DEV_PFLOG
-#define	NPFLOG		DEV_PFLOG
-#else
-#define	NPFLOG		0
-#endif
-
-#ifdef DEV_PFSYNC
-#define	NPFSYNC		DEV_PFSYNC
-#else
-#define	NPFSYNC		0
-#endif
+#define	NPFSYNC		1
 
 #ifdef DEV_PFLOW
 #define	NPFLOW		DEV_PFLOW

Modified: stable/9/sys/contrib/pf/net/pf_ioctl.c
==============================================================================
--- stable/9/sys/contrib/pf/net/pf_ioctl.c	Wed Feb  1 15:04:27 2012	(r230867)
+++ stable/9/sys/contrib/pf/net/pf_ioctl.c	Wed Feb  1 15:57:49 2012	(r230868)
@@ -44,11 +44,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_bpf.h"
 #include "opt_pf.h"
 
-#ifdef DEV_BPF
-#define		NBPFILTER	DEV_BPF
-#else
-#define		NBPFILTER	0
-#endif
+#define		NPFSYNC		1
 
 #ifdef DEV_PFLOG
 #define		NPFLOG		DEV_PFLOG
@@ -56,16 +52,10 @@ __FBSDID("$FreeBSD$");
 #define		NPFLOG		0
 #endif
 
-#ifdef DEV_PFSYNC
-#define		NPFSYNC		DEV_PFSYNC
-#else
-#define		NPFSYNC		0
-#endif
-
-#else
+#else /* !__FreeBSD__ */
 #include "pfsync.h"
 #include "pflog.h"
-#endif
+#endif /* __FreeBSD__ */
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -4328,57 +4318,25 @@ dehook_pf(void)
 	return (0);
 }
 
-/* Vnet accessors */
-static int
-vnet_pf_init(const void *unused) 
-{
-
-	V_pf_pfil_hooked = 0;
-	V_pf_end_threads = 0;
-
-	V_debug_pfugidhack = 0;
-
-	TAILQ_INIT(&V_pf_tags);
-	TAILQ_INIT(&V_pf_qids);
-
-	pf_load();
-
-	return (0);
-}
-
-static int
-vnet_pf_uninit(const void *unused)
-{
-
-	pf_unload();
-
-	return (0);
-}
-
-/* Define startup order. */
-#define	PF_SYSINIT_ORDER	SI_SUB_PROTO_BEGIN
-#define	PF_MODEVENT_ORDER	(SI_ORDER_FIRST) /* On boot slot in here. */
-#define	PF_VNET_ORDER		(PF_MODEVENT_ORDER + 2) /* Later still. */
-
-/*
- * Starting up.
- * VNET_SYSINIT is called for each existing vnet and each new vnet.
- */
-VNET_SYSINIT(vnet_pf_init, PF_SYSINIT_ORDER, PF_VNET_ORDER,
-    vnet_pf_init, NULL);
-
-/*
- * Closing up shop. These are done in REVERSE ORDER,
- * Not called on reboot.
- * VNET_SYSUNINIT is called for each exiting vnet as it exits.
- */
-VNET_SYSUNINIT(vnet_pf_uninit, PF_SYSINIT_ORDER, PF_VNET_ORDER,
-    vnet_pf_uninit, NULL);
-
 static int
 pf_load(void)
 {
+	VNET_ITERATOR_DECL(vnet_iter);
 
+	VNET_LIST_RLOCK();
+	VNET_FOREACH(vnet_iter) {
+		CURVNET_SET(vnet_iter);
+		V_pf_pfil_hooked = 0;
+		V_pf_end_threads = 0;
+		V_debug_pfugidhack = 0;
+		TAILQ_INIT(&V_pf_tags);
+		TAILQ_INIT(&V_pf_qids);
+		CURVNET_RESTORE();
+	}
+	VNET_LIST_RUNLOCK();
+
+	init_pf_mutex();
+	pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME);
 	init_zone_var();
 	sx_init(&V_pf_consistency_lock, "pf_statetbl_lock");
 	if (pfattach() < 0)
@@ -4395,6 +4353,7 @@ pf_unload(void)
 	PF_LOCK();
 	V_pf_status.running = 0;
 	PF_UNLOCK();
+	m_addr_chg_pf_p = NULL;
 	error = dehook_pf();
 	if (error) {
 		/*
@@ -4417,6 +4376,8 @@ pf_unload(void)
 	pf_osfp_cleanup();
 	cleanup_pf_zone();
 	PF_UNLOCK();
+	destroy_dev(pf_dev);
+	destroy_pf_mutex();
 	sx_destroy(&V_pf_consistency_lock);
 	return error;
 }
@@ -4428,12 +4389,16 @@ pf_modevent(module_t mod, int type, void
 
 	switch(type) {
 	case MOD_LOAD:
-		init_pf_mutex();
-		pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME);
+		error = pf_load();
+		break;
+	case MOD_QUIESCE:
+		/*
+		 * Module should not be unloaded due to race conditions.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-stable-9 mailing list