aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2024-03-24 15:08:52 +0000
committerKristof Provost <kp@FreeBSD.org>2024-04-01 07:33:36 +0000
commite0a58ef24a3baf5ed4cc09a798b9fe2d85408052 (patch)
tree7f1d7a1b8eb9157fc548e1bafb2ba5d4bd7b22f2
parent0ade521bac78929941081b6757e45316befd79f7 (diff)
downloadsrc-e0a58ef24a3baf5ed4cc09a798b9fe2d85408052.tar.gz
src-e0a58ef24a3baf5ed4cc09a798b9fe2d85408052.zip
pfsync: cope with multiple pending plus messages
It's possible for pfsync to add a plus message when one is already queued. Append both, rather than overwriting the already pending one. MFC after: 1 week (cherry picked from commit caccf6d3c008d3c778986734c2705cdae849a877)
-rw-r--r--sys/netpfil/pf/if_pfsync.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index a08a8334683a..d4d3c521a568 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -202,7 +202,7 @@ struct pfsync_bucket
TAILQ_HEAD(, pfsync_upd_req_item) b_upd_req_list;
TAILQ_HEAD(, pfsync_deferral) b_deferrals;
u_int b_deferred;
- void *b_plus;
+ uint8_t *b_plus;
size_t b_pluslen;
struct ifaltq b_snd;
@@ -421,6 +421,7 @@ pfsync_clone_destroy(struct ifnet *ifp)
free(b->b_plus, M_PFSYNC);
b->b_plus = NULL;
+ b->b_pluslen = 0;
callout_drain(&b->b_tmo);
}
@@ -1562,6 +1563,7 @@ pfsync_drop(struct pfsync_softc *sc)
b->b_len = PFSYNC_MINPKT;
free(b->b_plus, M_PFSYNC);
b->b_plus = NULL;
+ b->b_pluslen = 0;
}
}
@@ -1675,6 +1677,7 @@ pfsync_sendout(int schedswi, int c)
free(b->b_plus, M_PFSYNC);
b->b_plus = NULL;
+ b->b_pluslen = 0;
}
subh = (struct pfsync_subheader *)(m->m_data + offset);
@@ -2289,20 +2292,28 @@ pfsync_send_plus(void *plus, size_t pluslen)
{
struct pfsync_softc *sc = V_pfsyncif;
struct pfsync_bucket *b = &sc->sc_buckets[0];
+ uint8_t *newplus;
PFSYNC_BUCKET_LOCK(b);
- MPASS(b->b_plus == NULL);
-
if (b->b_len + pluslen > sc->sc_ifp->if_mtu)
pfsync_sendout(1, b->b_id);
- b->b_plus = malloc(pluslen, M_PFSYNC, M_NOWAIT);
- if (b->b_plus == NULL)
+ newplus = malloc(pluslen + b->b_pluslen, M_PFSYNC, M_NOWAIT);
+ if (newplus == NULL)
goto out;
- memcpy(b->b_plus, plus, pluslen);
- b->b_len += (b->b_pluslen = pluslen);
+ if (b->b_plus != NULL) {
+ memcpy(newplus, b->b_plus, b->b_pluslen);
+ free(b->b_plus, M_PFSYNC);
+ } else {
+ MPASS(b->b_pluslen == 0);
+ }
+ memcpy(newplus + b->b_pluslen, plus, pluslen);
+
+ b->b_plus = newplus;
+ b->b_pluslen += pluslen;
+ b->b_len += pluslen;
pfsync_sendout(1, b->b_id);