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