summaryrefslogtreecommitdiffstats
path: root/sys/contrib/pf/net/if_pfsync.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/pf/net/if_pfsync.c')
-rw-r--r--sys/contrib/pf/net/if_pfsync.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/sys/contrib/pf/net/if_pfsync.c b/sys/contrib/pf/net/if_pfsync.c
index 746a6ea..315342c 100644
--- a/sys/contrib/pf/net/if_pfsync.c
+++ b/sys/contrib/pf/net/if_pfsync.c
@@ -132,6 +132,7 @@ struct pfsyncstats pfsyncstats;
static void pfsync_clone_destroy(struct ifnet *);
static int pfsync_clone_create(struct if_clone *, int);
+static void pfsync_senddef(void *);
#else
void pfsyncattach(int);
#endif
@@ -174,6 +175,8 @@ pfsync_clone_destroy(struct ifnet *ifp)
callout_stop(&sc->sc_bulk_tmo);
callout_stop(&sc->sc_bulkfail_tmo);
+ callout_stop(&sc->sc_send_tmo);
+
#if NBPFILTER > 0
bpfdetach(ifp);
#endif
@@ -225,6 +228,9 @@ pfsync_clone_create(struct if_clone *ifc, int unit)
callout_init(&sc->sc_tmo, 0);
callout_init(&sc->sc_bulk_tmo, 0);
callout_init(&sc->sc_bulkfail_tmo, 0);
+ callout_init(&sc->sc_send_tmo, 0);
+ mtx_init(&sc->sc_ifq.ifq_mtx, ifp->if_xname, "pfsync send queue",
+ MTX_DEF);
if_attach(ifp);
LIST_INSERT_HEAD(&pfsync_list, sc, sc_next);
@@ -1038,6 +1044,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
if (pfsyncr.pfsyncr_maxupdates > 255)
return (EINVAL);
#ifdef __FreeBSD__
+ callout_drain(&sc->sc_send_tmo);
PF_LOCK();
#endif
sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
@@ -1794,15 +1801,13 @@ pfsync_sendout(sc)
#endif
pfsyncstats.pfsyncs_opackets++;
-
#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
+ if (IF_HANDOFF(&sc->sc_ifq, m, NULL))
+ pfsyncstats.pfsyncs_oerrors++;
+ callout_reset(&sc->sc_send_tmo, 1, pfsync_senddef, sc);
+#else
if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))
pfsyncstats.pfsyncs_oerrors++;
-
-#ifdef __FreeBSD__
- PF_LOCK();
#endif
} else
m_freem(m);
@@ -1810,8 +1815,22 @@ pfsync_sendout(sc)
return (0);
}
-
#ifdef __FreeBSD__
+static void
+pfsync_senddef(void *arg)
+{
+ struct pfsync_softc *sc = (struct pfsync_softc *)arg;
+ struct mbuf *m;
+
+ for(;;) {
+ IF_DEQUEUE(&sc->sc_ifq, m);
+ if (m == NULL)
+ break;
+ if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))
+ pfsyncstats.pfsyncs_oerrors++;
+ }
+}
+
static int
pfsync_modevent(module_t mod, int type, void *data)
{
OpenPOWER on IntegriCloud