Apply by doing:
cd /usr/src/sys
patch -p0 < 003_espdata.patch
And then rebuild your kernel.
--- netinet/ip_esp_new.c:1.40 Sun May 9 18:06:31 1999
+++ netinet/ip_esp_new.c Wed May 12 23:11:42 1999
@@ -781,7 +781,7 @@
struct ip *ip, ipo;
int i, ilen, ohlen, nh, rlen, plen, padding, rest;
struct esp_new espo;
- struct mbuf *mi, *mo;
+ struct mbuf *mi, *mo = (struct mbuf *) NULL;
u_char *pad, *idat, *odat, *ivp;
u_char iv[ESP_MAX_IVS], blk[ESP_MAX_BLKS], auth[AH_ALEN_MAX], opts[40];
union {
@@ -799,6 +799,39 @@
alen = 0;
espstat.esps_output++;
+
+ /*
+ * Loop through mbuf chain; if we find an M_EXT mbuf with
+ * more than one reference, replace the rest of the chain.
+ */
+ mi = m;
+ while (mi != NULL &&
+ (!(mi->m_flags & M_EXT) ||
+ mclrefcnt[mtocl(mi->m_ext.ext_buf)] <= 1))
+ {
+ mo = mi;
+ mi = mi->m_next;
+ }
+
+ if (mi != NULL)
+ {
+ /* Replace the rest of the mbuf chain. */
+ struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
+
+ if (n == NULL)
+ {
+ espstat.esps_hdrops++;
+ m_freem(m);
+ return ENOBUFS;
+ }
+
+ if (mo != NULL)
+ mo->m_next = n;
+ else
+ m = n;
+
+ m_freem(mi);
+ }
m = m_pullup(m, sizeof (struct ip)); /* Get IP header in one mbuf */
if (m == NULL)
--- netinet/ip_esp_old.c:1.31 Sun May 9 20:14:50 1999
+++ netinet/ip_esp_old.c Wed May 12 23:11:42 1999
@@ -505,7 +505,7 @@
struct ip *ip, ipo;
int i, ilen, ohlen, nh, rlen, plen, padding, rest;
u_int32_t spi;
- struct mbuf *mi, *mo;
+ struct mbuf *mi, *mo = (struct mbuf *) NULL;
u_char *pad, *idat, *odat, *ivp;
u_char iv[ESP_3DES_IVS], blk[ESP_3DES_IVS], opts[40];
int iphlen, blks;
@@ -513,6 +513,39 @@
blks = espx->blocksize;
espstat.esps_output++;
+
+ /*
+ * Loop through mbuf chain; if we find an M_EXT mbuf with
+ * more than one reference, replace the rest of the chain.
+ */
+ mi = m;
+ while (mi != NULL &&
+ (!(mi->m_flags & M_EXT) ||
+ mclrefcnt[mtocl(mi->m_ext.ext_buf)] <= 1))
+ {
+ mo = mi;
+ mi = mi->m_next;
+ }
+
+ if (mi != NULL)
+ {
+ /* Replace the rest of the mbuf chain. */
+ struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
+
+ if (n == NULL)
+ {
+ espstat.esps_hdrops++;
+ m_freem(m);
+ return ENOBUFS;
+ }
+
+ if (mo != NULL)
+ mo->m_next = n;
+ else
+ m = n;
+
+ m_freem(mi);
+ }
m = m_pullup(m, sizeof(struct ip));
if (m == NULL)