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