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