svn commit: r236526 - projects/pf/head/sys/contrib/pf/net

Gleb Smirnoff glebius at FreeBSD.org
Sun Jun 3 20:07:38 UTC 2012


Author: glebius
Date: Sun Jun  3 20:07:37 2012
New Revision: 236526
URL: http://svn.freebsd.org/changeset/base/236526

Log:
  pfsync_sendout() is usually called when softc has accumulated
  enough data to send a packet, and now is being requested to
  add data that would overflow a packet. Thus, swi scheduled
  at the end of pfsync_sendout() is going to service not a single
  packet, but a couple of them, and the second one is containg
  only one piece of pfsync data. This leads to coupling of pfsync
  pps: every odd packet is full-sized and every even is undersized.
  
  To fix this, a flag is added to softc - PFSYNCF_PUSH, which
  indicates, whether we swi handler needs to sqeeze data from the
  softc prior to sending packets.
  
  In all cases when we need to send data immidiately, this flags
  is raised prioir to swi_sched(). But in case of usual sc_len
  overflow, it isn't raised.

Modified:
  projects/pf/head/sys/contrib/pf/net/if_pfsync.c

Modified: projects/pf/head/sys/contrib/pf/net/if_pfsync.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/if_pfsync.c	Sun Jun  3 19:25:48 2012	(r236525)
+++ projects/pf/head/sys/contrib/pf/net/if_pfsync.c	Sun Jun  3 20:07:37 2012	(r236526)
@@ -203,6 +203,7 @@ struct pfsync_softc {
 	uint32_t		sc_flags;
 #define	PFSYNCF_OK		0x00000001
 #define	PFSYNCF_DEFER		0x00000002
+#define	PFSYNCF_PUSH		0x00000004
 	uint8_t			sc_maxupdates;
 	struct ip		sc_template;
 	struct callout		sc_tmo;
@@ -248,6 +249,7 @@ static VNET_DEFINE(int, pfsync_carp_adj)
 #define	V_pfsync_carp_adj	VNET(pfsync_carp_adj)
 
 static void	pfsync_timeout(void *);
+static void	pfsync_push(struct pfsync_softc *);
 static void	pfsyncintr(void *);
 static int	pfsync_multicast_setup(struct pfsync_softc *, struct ifnet *,
 		    void *);
@@ -417,6 +419,7 @@ pfsync_alloc_scrub_memory(struct pfsync_
 static int
 pfsync_state_import(struct pfsync_state *sp, u_int8_t flags)
 {
+	struct pfsync_softc *sc = V_pfsyncif;
 	struct pf_state	*st = NULL;
 	struct pf_state_key *skw = NULL, *sks = NULL;
 	struct pf_rule *r = NULL;
@@ -546,7 +549,7 @@ pfsync_state_import(struct pfsync_state 
 		st->state_flags &= ~PFSTATE_NOSYNC;
 		if (st->state_flags & PFSTATE_ACK) {
 			pfsync_q_ins(st, PFSYNC_S_IACK);
-			swi_sched(V_pfsync_swi_cookie, 0);
+			pfsync_push(sc);
 		}
 	}
 	st->state_flags &= ~PFSTATE_ACK;
@@ -826,6 +829,7 @@ pfsync_upd_tcp(struct pf_state *st, stru
 static int
 pfsync_in_upd(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
 {
+	struct pfsync_softc *sc = V_pfsyncif;
 	struct pfsync_state *sa, *sp;
 	struct pf_state_key *sk;
 	struct pf_state *st;
@@ -866,9 +870,9 @@ pfsync_in_upd(struct pfsync_pkt *pkt, st
 		}
 
 		if (st->state_flags & PFSTATE_ACK) {
-			PFSYNC_LOCK(V_pfsyncif);
+			PFSYNC_LOCK(sc);
 			pfsync_undefer_state(st, 1);
-			PFSYNC_UNLOCK(V_pfsyncif);
+			PFSYNC_UNLOCK(sc);
 		}
 
 		sk = st->key[PF_SK_WIRE];	/* XXX right one? */
@@ -898,7 +902,9 @@ pfsync_in_upd(struct pfsync_pkt *pkt, st
 
 			pfsync_update_state(st);
 			PF_STATE_UNLOCK(st);
-			swi_sched(V_pfsync_swi_cookie, 0);
+			PFSYNC_LOCK(sc);
+			pfsync_push(sc);
+			PFSYNC_UNLOCK(sc);
 			continue;
 		}
 		pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
@@ -916,6 +922,7 @@ pfsync_in_upd(struct pfsync_pkt *pkt, st
 static int
 pfsync_in_upd_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
 {
+	struct pfsync_softc *sc = V_pfsyncif;
 	struct pfsync_upd_c *ua, *up;
 	struct pf_state_key *sk;
 	struct pf_state *st;
@@ -952,16 +959,16 @@ pfsync_in_upd_c(struct pfsync_pkt *pkt, 
 		st = pf_find_state_byid(up->id, up->creatorid);
 		if (st == NULL) {
 			/* We don't have this state. Ask for it. */
-			PFSYNC_LOCK(V_pfsyncif);
+			PFSYNC_LOCK(sc);
 			pfsync_request_update(up->creatorid, up->id);
-			PFSYNC_UNLOCK(V_pfsyncif);
+			PFSYNC_UNLOCK(sc);
 			continue;
 		}
 
 		if (st->state_flags & PFSTATE_ACK) {
-			PFSYNC_LOCK(V_pfsyncif);
+			PFSYNC_LOCK(sc);
 			pfsync_undefer_state(st, 1);
-			PFSYNC_UNLOCK(V_pfsyncif);
+			PFSYNC_UNLOCK(sc);
 		}
 
 		sk = st->key[PF_SK_WIRE]; /* XXX right one? */
@@ -990,7 +997,9 @@ pfsync_in_upd_c(struct pfsync_pkt *pkt, 
 
 			pfsync_update_state(st);
 			PF_STATE_UNLOCK(st);
-			swi_sched(V_pfsync_swi_cookie, 0);
+			PFSYNC_LOCK(sc);
+			pfsync_push(sc);
+			PFSYNC_UNLOCK(sc);
 			continue;
 		}
 		pfsync_alloc_scrub_memory(&up->dst, &st->dst);
@@ -1712,7 +1721,7 @@ pfsync_defer(struct pf_state *st, struct
 	callout_init_mtx(&pd->pd_tmo, &sc->sc_mtx, CALLOUT_RETURNUNLOCKED);
 	callout_reset(&pd->pd_tmo, 10, pfsync_defer_tmo, pd);
 
-	swi_sched(V_pfsync_swi_cookie, 0);
+	pfsync_push(sc);
 
 	return (1);
 }
@@ -1736,7 +1745,7 @@ pfsync_undefer(struct pfsync_deferral *p
 		m_freem(m);
 	else {
 		_IF_ENQUEUE(&sc->sc_ifp->if_snd, m);
-		swi_sched(V_pfsync_swi_cookie, 0);
+		pfsync_push(sc);
 	}
 }
 
@@ -1829,10 +1838,11 @@ pfsync_update_state(struct pf_state *st)
 	default:
 		panic("%s: unexpected sync state %d", __func__, st->sync_state);
 	}
-	PFSYNC_UNLOCK(sc);
 
 	if (sync || (time_uptime - st->pfsync_time) < 2)
-		swi_sched(V_pfsync_swi_cookie, 0);
+		pfsync_push(sc);
+
+	PFSYNC_UNLOCK(sc);
 }
 
 static void
@@ -1868,7 +1878,7 @@ pfsync_request_update(u_int32_t creatori
 	TAILQ_INSERT_TAIL(&sc->sc_upd_req_list, item, ur_entry);
 	sc->sc_len += nlen;
 
-	swi_sched(V_pfsync_swi_cookie, 0);
+	pfsync_push(sc);
 }
 
 static void
@@ -1892,7 +1902,7 @@ pfsync_update_state_req(struct pf_state 
 		pfsync_q_del(st);
 	case PFSYNC_S_NONE:
 		pfsync_q_ins(st, PFSYNC_S_UPD);
-		swi_sched(V_pfsync_swi_cookie, 0);
+		pfsync_push(sc);
 		break;
 
 	case PFSYNC_S_INS:
@@ -2178,16 +2188,23 @@ pfsync_send_plus(void *plus, size_t plus
 static void
 pfsync_timeout(void *arg)
 {
-#ifdef VIMAGE
 	struct pfsync_softc *sc = arg;
-#endif
 
 	CURVNET_SET(sc->sc_ifp->if_vnet);
-	swi_sched(V_pfsync_swi_cookie, 0);
+	pfsync_push(sc);
 	CURVNET_RESTORE();
 }
 
-/* this is a softnet/netisr handler */
+static void
+pfsync_push(struct pfsync_softc *sc)
+{
+
+	PFSYNC_LOCK_ASSERT(sc);
+
+	sc->sc_flags |= PFSYNCF_PUSH;
+	swi_sched(V_pfsync_swi_cookie, 0);
+}
+
 static void
 pfsyncintr(void *arg)
 {
@@ -2197,8 +2214,10 @@ pfsyncintr(void *arg)
 	CURVNET_SET(sc->sc_ifp->if_vnet);
 
 	PFSYNC_LOCK(sc);
-	if (sc->sc_len > PFSYNC_MINPKT)
+	if ((sc->sc_flags & PFSYNCF_PUSH) && sc->sc_len > PFSYNC_MINPKT) {
 		pfsync_sendout(0);
+		sc->sc_flags &= ~PFSYNCF_PUSH;
+	}
 	_IF_DEQUEUE_ALL(&sc->sc_ifp->if_snd, m);
 	PFSYNC_UNLOCK(sc);
 


More information about the svn-src-projects mailing list