diff options
author | Kristof Provost <kp@FreeBSD.org> | 2024-03-24 15:08:52 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2024-04-01 07:33:36 +0000 |
commit | e0a58ef24a3baf5ed4cc09a798b9fe2d85408052 (patch) | |
tree | 7f1d7a1b8eb9157fc548e1bafb2ba5d4bd7b22f2 | |
parent | 0ade521bac78929941081b6757e45316befd79f7 (diff) | |
download | src-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.c | 25 |
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); |