svn commit: r197943 - user/eri/pf45/head/sys/contrib/pf/net
Ermal Luçi
eri at FreeBSD.org
Sat Oct 10 21:32:34 UTC 2009
Author: eri
Date: Sat Oct 10 21:32:33 2009
New Revision: 197943
URL: http://svn.freebsd.org/changeset/base/197943
Log:
* Lock pflow(4) list with pf(4) lock. More advanced schemas needs changes in pf(4) locking itself.
* Defer the sending of pflow(4) packets to avoid LORs.
Modified:
user/eri/pf45/head/sys/contrib/pf/net/if_pflow.c
user/eri/pf45/head/sys/contrib/pf/net/if_pflow.h
user/eri/pf45/head/sys/contrib/pf/net/if_pfsync.c
user/eri/pf45/head/sys/contrib/pf/net/pf.c
user/eri/pf45/head/sys/contrib/pf/net/pf_ioctl.c
user/eri/pf45/head/sys/contrib/pf/net/pfvar.h
Modified: user/eri/pf45/head/sys/contrib/pf/net/if_pflow.c
==============================================================================
--- user/eri/pf45/head/sys/contrib/pf/net/if_pflow.c Sat Oct 10 21:17:30 2009 (r197942)
+++ user/eri/pf45/head/sys/contrib/pf/net/if_pflow.c Sat Oct 10 21:32:33 2009 (r197943)
@@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$");
#ifdef __FreeBSD__
#include <machine/in_cksum.h>
#endif
+
#define PFLOW_MINMTU \
(sizeof(struct pflow_header) + sizeof(struct pflow_flow))
@@ -106,6 +107,7 @@ void pflowattach(int);
#ifdef __FreeBSD__
int pflow_clone_create(struct if_clone *, int, caddr_t);
void pflow_clone_destroy(struct ifnet *);
+void pflow_senddef(void *, int);
#else
int pflow_clone_create(struct if_clone *, int);
int pflow_clone_destroy(struct ifnet *);
@@ -205,10 +207,15 @@ pflow_clone_create(struct if_clone *ifc,
ifp->if_start = pflowstart;
ifp->if_type = IFT_PFLOW;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
+#ifdef __FreeBSD__
+ mtx_init(&pflowif->sc_ifq.ifq_mtx, ifp->if_xname,
+ "pflow send queue", MTX_DEF);
+ TASK_INIT(&pflowif->sc_send_task, 0, pflow_senddef, pflowif);
+#endif
ifp->if_hdrlen = PFLOW_HDRLEN;
ifp->if_flags = IFF_UP;
#ifdef __FreeBSD__
- ifp->if_flags &= ~IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
#else
ifp->if_flags &= ~IFF_RUNNING; /* not running, need receiver */
#endif
@@ -231,7 +238,13 @@ pflow_clone_create(struct if_clone *ifc,
#endif
#endif
/* Insert into list of pflows */
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
SLIST_INSERT_HEAD(&pflowif_list, pflowif, sc_next);
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
return (0);
}
@@ -251,8 +264,14 @@ pflow_clone_destroy(struct ifnet *ifp)
bpfdetach(ifp);
#endif
if_detach(ifp);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
SLIST_REMOVE(&pflowif_list, sc, pflow_softc, sc_next);
#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+#ifdef __FreeBSD__
free(sc->sc_imo.imo_membership, M_DEVBUF);
#else
free(sc->sc_imo.imo_membership, M_IPMOPTS);
@@ -699,7 +718,9 @@ pflow_sendout_mbuf(struct pflow_softc *s
struct ifnet *ifp = &sc->sc_if;
#endif
struct ip *ip;
+#ifndef __FreeBSD__
int err;
+#endif
/* UDP Header*/
M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
@@ -756,15 +777,21 @@ pflow_sendout_mbuf(struct pflow_softc *s
sc->sc_if.if_obytes += m->m_pkthdr.len;
#endif
- if ((err = ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))) {
- pflowstats.pflow_oerrors++;
#ifdef __FreeBSD__
- sc->sc_ifp->if_oerrors++;
+ if (!IF_HANDOFF(&sc->sc_ifq, m, NULL))
+ pflowstats.pflow_oerrors++;
+ taskqueue_enqueue(taskqueue_thread, &sc->sc_send_task);
#else
+ if ((err = ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL))) {
+ pflowstats.pflow_oerrors++;
sc->sc_if.if_oerrors++;
-#endif
}
+#endif
+#ifdef __FreeBSD__
+ return (0);
+#else
return (err);
+#endif
}
int
@@ -829,6 +856,23 @@ pflow_sysctl(int *name, u_int namelen, v
#endif
#ifdef __FreeBSD__
+void
+pflow_senddef(void *arg, __unused int pending)
+{
+ struct pflow_softc *sc = (struct pflow_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)) {
+ pflowstats.pflow_oerrors++;
+ sc->sc_ifp->if_oerrors++;
+ }
+ }
+}
+
static int
pflow_modevent(module_t mod, int type, void *data)
{
Modified: user/eri/pf45/head/sys/contrib/pf/net/if_pflow.h
==============================================================================
--- user/eri/pf45/head/sys/contrib/pf/net/if_pflow.h Sat Oct 10 21:17:30 2009 (r197942)
+++ user/eri/pf45/head/sys/contrib/pf/net/if_pflow.h Sat Oct 10 21:32:33 2009 (r197943)
@@ -73,6 +73,10 @@ struct pflow_softc {
#else
struct timeout sc_tmo;
#endif
+#ifdef __FreeBSD__
+ struct ifqueue sc_ifq;
+ struct task sc_send_task;
+#endif
struct in_addr sc_sender_ip;
u_int16_t sc_sender_port;
struct in_addr sc_receiver_ip;
Modified: user/eri/pf45/head/sys/contrib/pf/net/if_pfsync.c
==============================================================================
--- user/eri/pf45/head/sys/contrib/pf/net/if_pfsync.c Sat Oct 10 21:17:30 2009 (r197942)
+++ user/eri/pf45/head/sys/contrib/pf/net/if_pfsync.c Sat Oct 10 21:32:33 2009 (r197943)
@@ -3044,6 +3044,7 @@ pfsync_modevent(module_t mod, int type,
pfsync_update_state_ptr = pfsync_update_state;
pfsync_delete_state_ptr = pfsync_delete_state;
pfsync_clear_states_ptr = pfsync_clear_states;
+ pfsync_state_in_use_ptr = pfsync_state_in_use;
pfsync_defer_ptr = pfsync_defer;
#endif
break;
@@ -3057,6 +3058,7 @@ pfsync_modevent(module_t mod, int type,
pfsync_update_state_ptr = NULL;
pfsync_delete_state_ptr = NULL;
pfsync_clear_states_ptr = NULL;
+ pfsync_state_in_use_ptr = NULL;
pfsync_defer_ptr = NULL;
#endif
if_clone_detach(&pfsync_cloner);
Modified: user/eri/pf45/head/sys/contrib/pf/net/pf.c
==============================================================================
--- user/eri/pf45/head/sys/contrib/pf/net/pf.c Sat Oct 10 21:17:30 2009 (r197942)
+++ user/eri/pf45/head/sys/contrib/pf/net/pf.c Sat Oct 10 21:32:33 2009 (r197943)
@@ -1370,7 +1370,12 @@ pf_free_state(struct pf_state *cur)
#endif
#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_state_in_use_ptr != NULL)
+ pfsync_state_in_use_ptr(cur);
+#else
if (pfsync_state_in_use(cur))
+#endif
return;
#endif
#ifdef __FreeBSD__
@@ -3437,7 +3442,7 @@ pf_test_rule(struct pf_rule **rm, struct
*/
#ifdef __FreeBSD__
if (pfsync_defer_ptr != NULL)
- pfsync_defer(*sm, m);
+ pfsync_defer_ptr(*sm, m);
#else
if (pfsync_defer(*sm, m))
#endif
Modified: user/eri/pf45/head/sys/contrib/pf/net/pf_ioctl.c
==============================================================================
--- user/eri/pf45/head/sys/contrib/pf/net/pf_ioctl.c Sat Oct 10 21:17:30 2009 (r197942)
+++ user/eri/pf45/head/sys/contrib/pf/net/pf_ioctl.c Sat Oct 10 21:32:33 2009 (r197943)
@@ -248,12 +248,13 @@ static struct cdevsw pf_cdevsw = {
#ifdef __FreeBSD__
/* pfsync */
pfsync_state_import_t *pfsync_state_import_ptr = NULL;
- pfsync_up_t *pfsync_up_ptr = NULL;
pfsync_insert_state_t *pfsync_insert_state_ptr = NULL;
pfsync_update_state_t *pfsync_update_state_ptr = NULL;
pfsync_delete_state_t *pfsync_delete_state_ptr = NULL;
pfsync_clear_states_t *pfsync_clear_states_ptr = NULL;
+ pfsync_state_in_use_t *pfsync_state_in_use_ptr = NULL;
pfsync_defer_t *pfsync_defer_ptr = NULL;
+ pfsync_up_t *pfsync_up_ptr = NULL;
/* pflow */
export_pflow_t *export_pflow_ptr = NULL;
#if NPFLOG >0
Modified: user/eri/pf45/head/sys/contrib/pf/net/pfvar.h
==============================================================================
--- user/eri/pf45/head/sys/contrib/pf/net/pfvar.h Sat Oct 10 21:17:30 2009 (r197942)
+++ user/eri/pf45/head/sys/contrib/pf/net/pfvar.h Sat Oct 10 21:32:33 2009 (r197943)
@@ -931,20 +931,22 @@ struct pfsync_state {
#ifdef __FreeBSD__
/* pfsync */
typedef int pfsync_state_import_t(struct pfsync_state *, u_int8_t);
-typedef int pfsync_up_t(void);
typedef void pfsync_insert_state_t(struct pf_state *);
typedef void pfsync_update_state_t(struct pf_state *);
typedef void pfsync_delete_state_t(struct pf_state *);
typedef void pfsync_clear_states_t(u_int32_t, const char *);
+typedef int pfsync_state_in_use_t(struct pf_state *);
typedef int pfsync_defer_t(struct pf_state *, struct mbuf *);
+typedef int pfsync_up_t(void);
extern pfsync_state_import_t *pfsync_state_import_ptr;
-extern pfsync_up_t *pfsync_up_ptr;
extern pfsync_insert_state_t *pfsync_insert_state_ptr;
extern pfsync_update_state_t *pfsync_update_state_ptr;
extern pfsync_delete_state_t *pfsync_delete_state_ptr;
extern pfsync_clear_states_t *pfsync_clear_states_ptr;
+extern pfsync_state_in_use_t *pfsync_state_in_use_ptr;
extern pfsync_defer_t *pfsync_defer_ptr;
+extern pfsync_up_t *pfsync_up_ptr;
void pfsync_state_export(struct pfsync_state *,
struct pf_state *);
More information about the svn-src-user
mailing list