summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-03-28 20:03:10 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-03-28 20:03:10 +0000
commit3ddeb82e5920fb4ce16a363a4cdf2ff420fc6f8c (patch)
tree21df0560d7db7bab293cc22bc52b21fd5727de8a
parent59779d47329c2626433e1ab0d847e7d7cd41aa48 (diff)
Allow tdbi's to appear in mbufs throughout the stack; this allows
security properties of the packets to be pushed up to the application (not done yet). Eventually, this will be turned into a packet attributes framework. Make sure tdbi's are free'd/cleared properly whenever drivers (or NFS) does weird things with mbufs.
-rw-r--r--sys/dev/ic/awi_wep.c5
-rw-r--r--sys/dev/pci/hifn7751.c4
-rw-r--r--sys/dev/pci/ises.c4
-rw-r--r--sys/dev/pci/ubsec.c4
-rw-r--r--sys/kern/uipc_mbuf.c13
-rw-r--r--sys/kern/uipc_mbuf2.c4
-rw-r--r--sys/net/pfkeyv2.c83
-rw-r--r--sys/net/pfkeyv2.h5
-rw-r--r--sys/net/pfkeyv2_parsemessage.c7
-rw-r--r--sys/netinet/in_pcb.c10
-rw-r--r--sys/netinet/in_pcb.h8
-rw-r--r--sys/netinet/ip_ah.c7
-rw-r--r--sys/netinet/ip_esp.c7
-rw-r--r--sys/netinet/ip_icmp.c26
-rw-r--r--sys/netinet/ip_input.c86
-rw-r--r--sys/netinet/ip_ipip.c45
-rw-r--r--sys/netinet/ip_ipsp.c103
-rw-r--r--sys/netinet/ip_ipsp.h18
-rw-r--r--sys/netinet/ip_output.c24
-rw-r--r--sys/netinet/ip_spd.c10
-rw-r--r--sys/netinet/ipsec_input.c28
-rw-r--r--sys/netinet/ipsec_output.c10
-rw-r--r--sys/netinet/tcp_input.c66
-rw-r--r--sys/netinet/udp_usrreq.c35
-rw-r--r--sys/netinet6/icmp6.c7
-rw-r--r--sys/netinet6/ip6_output.c27
-rw-r--r--sys/nfs/nfs_socket.c14
-rw-r--r--sys/sys/mbuf.h38
28 files changed, 335 insertions, 363 deletions
diff --git a/sys/dev/ic/awi_wep.c b/sys/dev/ic/awi_wep.c
index 87f968130f2..2eb136fb9c1 100644
--- a/sys/dev/ic/awi_wep.c
+++ b/sys/dev/ic/awi_wep.c
@@ -327,8 +327,9 @@ awi_wep_encrypt(sc, m0, txflag)
n0 = n;
if (n == NULL)
goto fail;
- M_COPY_PKTHDR(n, m);
- len = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
+ M_DUP_PKTHDR(n, m);
+ len = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
+ IEEE80211_WEP_CRCLEN;
if (txflag) {
n->m_pkthdr.len += len;
} else {
diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c
index 4115b8a573f..4f3e42d4942 100644
--- a/sys/dev/pci/hifn7751.c
+++ b/sys/dev/pci/hifn7751.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751.c,v 1.55 2001/02/18 18:29:27 deraadt Exp $ */
+/* $OpenBSD: hifn7751.c,v 1.56 2001/03/28 20:02:59 angelos Exp $ */
/*
* Invertex AEON / Hi/fn 7751 driver
@@ -876,7 +876,7 @@ hifn_crypto(sc, cmd)
if (m == NULL)
return (-1);
if (len == MHLEN)
- M_COPY_PKTHDR(m, cmd->src_m);
+ M_DUP_PKTHDR(m, cmd->src_m);
if (totlen >= MINCLSIZE) {
MCLGET(m, M_DONTWAIT);
if (m->m_flags & M_EXT)
diff --git a/sys/dev/pci/ises.c b/sys/dev/pci/ises.c
index a4c1899a450..3288e67881e 100644
--- a/sys/dev/pci/ises.c
+++ b/sys/dev/pci/ises.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ises.c,v 1.3 2001/01/30 14:07:44 ho Exp $ */
+/* $OpenBSD: ises.c,v 1.4 2001/03/28 20:02:59 angelos Exp $ */
/*
* Copyright (c) 2000 Håkan Olsson (ho@crt.se)
@@ -1048,7 +1048,7 @@ ises_process(struct cryptop *crp)
totlen = q->q_dst_l = q->q_src_l;
if (q->q_src_m->m_flags & M_PKTHDR) {
MGETHDR(m, M_DONTWAIT, MT_DATA);
- M_COPY_PKTHDR(m, q->q_src_m);
+ M_DUP_PKTHDR(m, q->q_src_m);
len = MHLEN;
} else {
MGET(m, M_DONTWAIT, MT_DATA);
diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c
index b1c4769f57b..8a1342008b8 100644
--- a/sys/dev/pci/ubsec.c
+++ b/sys/dev/pci/ubsec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ubsec.c,v 1.41 2001/03/25 07:59:25 csapuntz Exp $ */
+/* $OpenBSD: ubsec.c,v 1.42 2001/03/28 20:03:00 angelos Exp $ */
/*
* Copyright (c) 2000 Jason L. Wright (jason@thought.net)
@@ -839,7 +839,7 @@ ubsec_process(crp)
goto errout;
}
if (len == MHLEN)
- M_COPY_PKTHDR(m, q->q_src_m);
+ M_DUP_PKTHDR(m, q->q_src_m);
if (totlen >= MINCLSIZE) {
MCLGET(m, M_DONTWAIT);
if (m->m_flags & M_EXT)
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 1b33e500d99..ae876576c49 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf.c,v 1.23 2001/03/25 07:07:57 csapuntz Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.24 2001/03/28 20:03:00 angelos Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@@ -279,6 +279,7 @@ m_prepend(m, len, how)
if (m->m_flags & M_PKTHDR) {
M_COPY_PKTHDR(mn, m);
m->m_flags &= ~M_PKTHDR;
+ m->m_pkthdr.tdbi = NULL;
}
mn->m_next = m;
m = mn;
@@ -621,6 +622,7 @@ m_pullup(n, len)
if (n->m_flags & M_PKTHDR) {
M_COPY_PKTHDR(m, n);
n->m_flags &= ~M_PKTHDR;
+ n->m_pkthdr.tdbi = NULL;
}
}
space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
@@ -691,6 +693,7 @@ m_pullup2(n, len)
m->m_pkthdr = n->m_pkthdr;
m->m_flags = (n->m_flags & M_COPYFLAGS) | M_EXT;
n->m_flags &= ~M_PKTHDR;
+ n->m_pkthdr.tdbi = NULL;
/* n->m_data is cool. */
}
}
@@ -782,9 +785,10 @@ m_inject(m0, len0, siz, wait)
return (NULL);
remain = m->m_len - len;
if (remain == 0) {
- if ((m->m_next) && (M_LEADINGSPACE(m->m_next) >= siz)) {
+ if ((m->m_next) && (M_LEADINGSPACE(m->m_next) >= siz)) {
m->m_next->m_len += siz;
- m0->m_pkthdr.len += siz;
+ if (m0->m_flags & M_PKTHDR)
+ m0->m_pkthdr.len += siz;
m->m_next->m_data -= siz;
return m->m_next;
}
@@ -839,7 +843,7 @@ m_split(m0, len0, wait)
MGETHDR(n, wait, m0->m_type);
if (n == NULL)
return (NULL);
- n->m_pkthdr = m0->m_pkthdr;
+ M_DUP_PKTHDR(n, m0);
n->m_pkthdr.len -= len0;
olen = m0->m_pkthdr.len;
m0->m_pkthdr.len = len0;
@@ -886,6 +890,7 @@ extpacket:
m->m_next = NULL;
return (n);
}
+
/*
* Routine to copy from device local memory into mbufs.
*/
diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c
index 2725dc389bc..d1b437b5944 100644
--- a/sys/kern/uipc_mbuf2.c
+++ b/sys/kern/uipc_mbuf2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf2.c,v 1.5 2001/02/14 17:04:34 itojun Exp $ */
+/* $OpenBSD: uipc_mbuf2.c,v 1.6 2001/03/28 20:03:00 angelos Exp $ */
/* $KAME: uipc_mbuf2.c,v 1.29 2001/02/14 13:42:10 itojun Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.40 1999/04/01 00:23:25 thorpej Exp $ */
@@ -261,7 +261,7 @@ m_dup1(m, off, len, wait)
return NULL;
if (copyhdr)
- M_COPY_PKTHDR(n, m);
+ M_DUP_PKTHDR(n, m);
m_copydata(m, off, len, mtod(n, caddr_t));
return n;
}
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c
index 543faa42898..66ccadf5bab 100644
--- a/sys/net/pfkeyv2.c
+++ b/sys/net/pfkeyv2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.c,v 1.57 2001/03/27 14:45:21 art Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.58 2001/03/28 20:03:01 angelos Exp $ */
/*
%%% copyright-nrl-97
This software is Copyright 1997-1998 by Randall Atkinson, Ronald Lee,
@@ -66,7 +66,7 @@ static struct sadb_alg aalgs[] =
void export_address(void **, struct sockaddr *);
void export_identity(void **, struct tdb *, int);
void export_lifetime(void **, struct tdb *, int);
-void export_credentials(void **, struct tdb *);
+void export_credentials(void **, struct tdb *, int);
void export_sa(void **, struct tdb *);
void export_key(void **, struct tdb *, int);
@@ -74,7 +74,7 @@ void import_address(struct sockaddr *, struct sadb_address *);
void import_identity(struct tdb *, struct sadb_ident *, int);
void import_key(struct ipsecinit *, struct sadb_key *, int);
void import_lifetime(struct tdb *, struct sadb_lifetime *, int);
-void import_credentials(struct tdb *, struct sadb_cred *);
+void import_credentials(struct tdb *, struct sadb_cred *, int);
void import_sa(struct tdb *, struct sadb_sa *, struct ipsecinit *);
int pfkeyv2_create(struct socket *);
@@ -487,17 +487,29 @@ export_address(void **p, struct sockaddr *sa)
* Import a set of credentials into the TDB.
*/
void
-import_credentials(struct tdb *tdb, struct sadb_cred *sadb_cred)
+import_credentials(struct tdb *tdb, struct sadb_cred *sadb_cred, int dstcred)
{
if (!sadb_cred)
return;
- tdb->tdb_cred_len = EXTLEN(sadb_cred) - sizeof(struct sadb_cred);
- tdb->tdb_cred_type = sadb_cred->sadb_cred_type;
- MALLOC(tdb->tdb_credentials, caddr_t, tdb->tdb_cred_len, M_XDATA,
- M_WAITOK);
- bcopy((void *) sadb_cred + sizeof(struct sadb_cred),
- tdb->tdb_credentials, tdb->tdb_cred_len);
+ if (dstcred)
+ {
+ tdb->tdb_dst_cred_len = EXTLEN(sadb_cred) - sizeof(struct sadb_cred);
+ tdb->tdb_dst_cred_type = sadb_cred->sadb_cred_type;
+ MALLOC(tdb->tdb_dst_credentials, caddr_t, tdb->tdb_dst_cred_len,
+ M_XDATA, M_WAITOK);
+ bcopy((void *) sadb_cred + sizeof(struct sadb_cred),
+ tdb->tdb_dst_credentials, tdb->tdb_dst_cred_len);
+ }
+ else
+ {
+ tdb->tdb_src_cred_len = EXTLEN(sadb_cred) - sizeof(struct sadb_cred);
+ tdb->tdb_src_cred_type = sadb_cred->sadb_cred_type;
+ MALLOC(tdb->tdb_src_credentials, caddr_t, tdb->tdb_src_cred_len,
+ M_XDATA, M_WAITOK);
+ bcopy((void *) sadb_cred + sizeof(struct sadb_cred),
+ tdb->tdb_src_credentials, tdb->tdb_src_cred_len);
+ }
}
/*
@@ -532,17 +544,30 @@ import_identity(struct tdb *tdb, struct sadb_ident *sadb_ident, int type)
}
void
-export_credentials(void **p, struct tdb *tdb)
+export_credentials(void **p, struct tdb *tdb, int dstcred)
{
struct sadb_cred *sadb_cred = (struct sadb_cred *) *p;
- sadb_cred->sadb_cred_len = (sizeof(struct sadb_cred) +
- PADUP(tdb->tdb_cred_len)) /
- sizeof(uint64_t);
- sadb_cred->sadb_cred_type = tdb->tdb_cred_type;
- *p += sizeof(struct sadb_cred);
- bcopy(tdb->tdb_credentials, *p, tdb->tdb_cred_len);
- *p += PADUP(tdb->tdb_cred_len);
+ if (dstcred)
+ {
+ sadb_cred->sadb_cred_len = (sizeof(struct sadb_cred) +
+ PADUP(tdb->tdb_dst_cred_len)) /
+ sizeof(uint64_t);
+ sadb_cred->sadb_cred_type = tdb->tdb_dst_cred_type;
+ *p += sizeof(struct sadb_cred);
+ bcopy(tdb->tdb_dst_credentials, *p, tdb->tdb_dst_cred_len);
+ *p += PADUP(tdb->tdb_dst_cred_len);
+ }
+ else
+ {
+ sadb_cred->sadb_cred_len = (sizeof(struct sadb_cred) +
+ PADUP(tdb->tdb_src_cred_len)) /
+ sizeof(uint64_t);
+ sadb_cred->sadb_cred_type = tdb->tdb_src_cred_type;
+ *p += sizeof(struct sadb_cred);
+ bcopy(tdb->tdb_src_credentials, *p, tdb->tdb_src_cred_len);
+ *p += PADUP(tdb->tdb_src_cred_len);
+ }
}
void
@@ -1034,10 +1059,16 @@ pfkeyv2_get(struct tdb *sa, void **headers, void **buffer)
}
/* Export credentials, if present */
- if (sa->tdb_credentials)
+ if (sa->tdb_src_credentials)
+ {
+ headers[SADB_X_EXT_SRC_CREDENTIALS] = p;
+ export_credentials(&p, sa, 0);
+ }
+
+ if (sa->tdb_dst_credentials)
{
- headers[SADB_X_EXT_CREDENTIALS] = p;
- export_credentials(&p, sa);
+ headers[SADB_X_EXT_DST_CREDENTIALS] = p;
+ export_credentials(&p, sa, 1);
}
/* Export authentication key, if present */
@@ -1353,7 +1384,10 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
PFKEYV2_IDENTITY_SRC);
import_identity(newsa, headers[SADB_EXT_IDENTITY_DST],
PFKEYV2_IDENTITY_DST);
- import_credentials(newsa, headers[SADB_X_EXT_CREDENTIALS]);
+ import_credentials(newsa, headers[SADB_X_EXT_SRC_CREDENTIALS],
+ 0);
+ import_credentials(newsa, headers[SADB_X_EXT_DST_CREDENTIALS],
+ 1);
headers[SADB_EXT_KEY_AUTH] = NULL;
headers[SADB_EXT_KEY_ENCRYPT] = NULL;
@@ -1468,7 +1502,10 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
import_identity(newsa, headers[SADB_EXT_IDENTITY_DST],
PFKEYV2_IDENTITY_DST);
- import_credentials(newsa, headers[SADB_X_EXT_CREDENTIALS]);
+ import_credentials(newsa, headers[SADB_X_EXT_SRC_CREDENTIALS],
+ 0);
+ import_credentials(newsa, headers[SADB_X_EXT_DST_CREDENTIALS],
+ 1);
headers[SADB_EXT_KEY_AUTH] = NULL;
headers[SADB_EXT_KEY_ENCRYPT] = NULL;
diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h
index e1cd7757c0c..24f89895fe5 100644
--- a/sys/net/pfkeyv2.h
+++ b/sys/net/pfkeyv2.h
@@ -200,8 +200,9 @@ struct sadb_cred {
#define SADB_X_EXT_SA2 23
#define SADB_X_EXT_DST2 24
#define SADB_X_EXT_POLICY 25
-#define SADB_X_EXT_CREDENTIALS 26
-#define SADB_EXT_MAX 26
+#define SADB_X_EXT_SRC_CREDENTIALS 26
+#define SADB_X_EXT_DST_CREDENTIALS 27
+#define SADB_EXT_MAX 27
/* Fix pfkeyv2.c struct pfkeyv2_socket if SATYPE_MAX > 31 */
#define SADB_SATYPE_UNSPEC 0
diff --git a/sys/net/pfkeyv2_parsemessage.c b/sys/net/pfkeyv2_parsemessage.c
index 8d813c93514..d48831f17d3 100644
--- a/sys/net/pfkeyv2_parsemessage.c
+++ b/sys/net/pfkeyv2_parsemessage.c
@@ -60,7 +60,9 @@ you didn't get a copy, you may request one from <license@inner.net>.
#define BITMAP_X_SA2 (1 << SADB_X_EXT_SA2)
#define BITMAP_X_DST2 (1 << SADB_X_EXT_DST2)
#define BITMAP_X_POLICY (1 << SADB_X_EXT_POLICY)
-#define BITMAP_X_CREDENTIALS (1 << SADB_X_EXT_CREDENTIALS)
+#define BITMAP_X_SRC_CREDENTIALS (1 << SADB_X_EXT_SRC_CREDENTIALS)
+#define BITMAP_X_DST_CREDENTIALS (1 << SADB_X_EXT_DST_CREDENTIALS)
+#define BITMAP_X_CREDENTIALS (BITMAP_X_SRC_CREDENTIALS | BITMAP_X_DST_CREDENTIALS)
uint32_t sadb_exts_allowed_in[SADB_MAX+1] =
{
@@ -415,7 +417,8 @@ pfkeyv2_parsemessage(void *p, int len, void **headers)
return EINVAL;
}
break;
- case SADB_X_EXT_CREDENTIALS:
+ case SADB_X_EXT_SRC_CREDENTIALS:
+ case SADB_X_EXT_DST_CREDENTIALS:
{
struct sadb_cred *sadb_cred = (struct sadb_cred *)p;
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 2abc99a5c4b..ef54a590596 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.49 2001/02/08 18:46:22 itojun Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.50 2001/03/28 20:03:02 angelos Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -554,8 +554,12 @@ in_pcbdetach(v)
#ifdef IPSEC
/* XXX IPsec cleanup here */
s = spltdb();
- if (inp->inp_tdb)
- TAILQ_REMOVE(&inp->inp_tdb->tdb_inp, inp, inp_tdb_next);
+ if (inp->inp_tdb_in)
+ TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in,
+ inp, inp_tdb_in_next);
+ if (inp->inp_tdb_out)
+ TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp,
+ inp_tdb_out_next);
splx(s);
#endif
s = splnet();
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index de65f08b901..cdce9721bb9 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.h,v 1.32 2001/02/16 16:00:53 itojun Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.33 2001/03/28 20:03:02 angelos Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@@ -122,7 +122,7 @@ struct inpcb {
} inp_mou;
#define inp_moptions inp_mou.mou_mo
#define inp_moptions6 inp_mou.mou_mo6
- u_char inp_seclevel[3]; /* Only the first 3 are used for now */
+ u_char inp_seclevel[3];
#define SL_AUTH 0 /* Authentication level */
#define SL_ESP_TRANS 1 /* ESP transport level */
#define SL_ESP_NETWORK 2 /* ESP network (encapsulation) level */
@@ -131,8 +131,8 @@ struct inpcb {
#define SR_FAILED 1 /* Negotiation failed permanently */
#define SR_SUCCESS 2 /* SA successfully established */
#define SR_WAIT 3 /* Waiting for SA */
- TAILQ_ENTRY(inpcb) inp_tdb_next;
- struct tdb *inp_tdb; /* If tdb_dst matches our dst, use */
+ TAILQ_ENTRY(inpcb) inp_tdb_in_next, inp_tdb_out_next;
+ struct tdb *inp_tdb_in, *inp_tdb_out;
#define inp_flowinfo inp_hu.hu_ipv6.ip6_flow
int in6p_cksum;
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index 7845272b22c..3afe50155e6 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.47 2001/03/15 06:30:58 mickey Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.48 2001/03/28 20:03:02 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -880,10 +880,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
m1.m_len = ENC_HDRLEN;
m1.m_data = (char *) &hdr;
- if (tdb->tdb_interface)
- ifn = (struct ifnet *) tdb->tdb_interface;
- else
- ifn = &(encif[0].sc_if);
+ ifn = &(encif[0].sc_if);
if (ifn->if_bpf)
bpf_mtap(ifn->if_bpf, &m1);
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index 5050c4820eb..e6889dc624f 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.c,v 1.53 2001/03/23 04:27:33 angelos Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.54 2001/03/28 20:03:03 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -723,10 +723,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
m1.m_len = ENC_HDRLEN;
m1.m_data = (char *) &hdr;
- if (tdb->tdb_interface)
- ifn = (struct ifnet *) tdb->tdb_interface;
- else
- ifn = &(encif[0].sc_if);
+ ifn = &(encif[0].sc_if);
if (ifn->if_bpf)
bpf_mtap(ifn->if_bpf, &m1);
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index cdea350447c..fab0f4352b0 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.32 2001/03/07 20:57:20 brian Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.33 2001/03/28 20:03:03 angelos Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -367,6 +367,13 @@ icmp_input(m, va_alist)
code = PRC_QUENCH;
deliver:
/*
+ * Free packet atttributes. XXX
+ */
+ if ((m->m_flags & M_PKTHDR) && (m->m_pkthdr.tdbi)) {
+ free(m->m_pkthdr.tdbi, M_TEMP);
+ m->m_pkthdr.tdbi = NULL;
+ }
+ /*
* Problem with datagram; advise higher level routines.
*/
if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
@@ -466,6 +473,13 @@ icmp_input(m, va_alist)
ip->ip_src = ia->ia_dstaddr.sin_addr;
}
reflect:
+ /*
+ * Free packet atttributes. XXX
+ */
+ if ((m->m_flags & M_PKTHDR) && (m->m_pkthdr.tdbi)) {
+ free(m->m_pkthdr.tdbi, M_TEMP);
+ m->m_pkthdr.tdbi = NULL;
+ }
ip->ip_len += hlen; /* since ip_input deducts this */
icmpstat.icps_reflect++;
icmpstat.icps_outhist[icp->icmp_type]++;
@@ -473,6 +487,13 @@ reflect:
return;
case ICMP_REDIRECT:
+ /*
+ * Free packet atttributes. XXX
+ */
+ if ((m->m_flags & M_PKTHDR) && (m->m_pkthdr.tdbi)) {
+ free(m->m_pkthdr.tdbi, M_TEMP);
+ m->m_pkthdr.tdbi = NULL;
+ }
if (code > 3)
goto badcode;
if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) ||
@@ -567,8 +588,7 @@ icmp_reflect(m)
m->m_pkthdr.rcvif));
/*
* The following happens if the packet was not addressed to us,
- * and was received on an interface with no IP address (like an
- * enc interface).
+ * and was received on an interface with no IP address.
*/
if (ia == (struct in_ifaddr *)0) {
struct sockaddr_in *dst;
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 4496ef5ccbf..3c593f7b19f 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.65 2001/03/25 05:51:31 csapuntz Exp $ */
+/* $OpenBSD: ip_input.c,v 1.66 2001/03/28 20:03:03 angelos Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -81,8 +81,6 @@
#define IPSENDREDIRECTS 1
#endif
-#define PI_MAGIC 0xdeadbeef /* XXX the horror! */
-
#ifndef IPMTUDISC
#define IPMTUDISC 1
#endif
@@ -310,22 +308,9 @@ ipv4_input(struct mbuf *m, ...)
extra = va_arg(ap, int);
va_end(ap);
-#ifdef IPSEC
- tdbi = (struct tdb_ident *) m->m_pkthdr.tdbi;
- if (tdbi == (void *) PI_MAGIC)
- tdbi = NULL;
-#endif /* IPSEC */
-
if (extra) {
struct mbuf *newpacket;
-#ifdef IPSEC
- if (tdbi) {
- free(tdbi, M_TEMP);
- tdbi = NULL;
- }
-#endif /* IPSEC */
-
if (!(newpacket = m_split(m, extra, M_NOWAIT))) {
m_freem(m);
return;
@@ -347,10 +332,6 @@ ipv4_input(struct mbuf *m, ...)
if (m->m_len < sizeof (struct ip) &&
(m = m_pullup(m, sizeof (struct ip))) == 0) {
ipstat.ips_toosmall++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
ip = mtod(m, struct ip *);
@@ -366,10 +347,6 @@ ipv4_input(struct mbuf *m, ...)
if (hlen > m->m_len) {
if ((m = m_pullup(m, hlen)) == 0) {
ipstat.ips_badhlen++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
ip = mtod(m, struct ip *);
@@ -426,17 +403,9 @@ ipv4_input(struct mbuf *m, ...)
{
struct mbuf *m0 = m;
if (fr_checkp && (*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m0)) {
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
if (m0 == 0) { /* in case of 'fastroute' */
-#ifdef IPSEC
- if (tdbi)
- free (tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
ip = mtod(m = m0, struct ip *);
@@ -451,10 +420,6 @@ ipv4_input(struct mbuf *m, ...)
*/
ip_nhops = 0; /* for source routed packets */
if (hlen > sizeof (struct ip) && ip_dooptions(m)) {
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
@@ -473,10 +438,6 @@ ipv4_input(struct mbuf *m, ...)
if (m->m_flags & M_EXT) {
if ((m = m_pullup(m, hlen)) == 0) {
ipstat.ips_toosmall++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
ip = mtod(m, struct ip *);
@@ -498,10 +459,6 @@ ipv4_input(struct mbuf *m, ...)
ip->ip_id = htons(ip->ip_id);
if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) {
ipstat.ips_cantforward++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
return;
}
@@ -525,10 +482,6 @@ ipv4_input(struct mbuf *m, ...)
if (inm == NULL) {
ipstat.ips_cantforward++;
m_freem(m);
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
goto ours;
@@ -542,15 +495,12 @@ ipv4_input(struct mbuf *m, ...)
*/
if (ipforwarding == 0) {
ipstat.ips_cantforward++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
} else {
#ifdef IPSEC
/* IPsec policy check for forwarded packets */
s = splnet();
+ tdbi = (struct tdb_ident *) m->m_pkthdr.tdbi;
if (tdbi == NULL)
tdb = NULL;
else
@@ -567,11 +517,6 @@ ipv4_input(struct mbuf *m, ...)
return;
}
- if (tdbi) {
- free(tdbi, M_TEMP);
- m->m_pkthdr.tdbi = NULL;
- }
-
/* Fall through, forward packet */
#endif /* IPSEC */
@@ -591,10 +536,6 @@ ours:
if (m->m_flags & M_EXT) { /* XXX */
if ((m = m_pullup(m, hlen)) == 0) {
ipstat.ips_toosmall++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
ip = mtod(m, struct ip *);
@@ -661,10 +602,6 @@ found:
ip = ip_reass(ipqe, fp);
if (ip == 0) {
ipq_unlock();
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
ipstat.ips_reassembled++;
@@ -697,7 +634,7 @@ found:
* to deal with that).
*/
if ((ip->ip_p == IPPROTO_IPIP) || (ip->ip_p == IPPROTO_IPV6))
- goto skipipsec2;
+ goto skipipsec;
/*
* If the protected packet is TCP or UDP, we'll do the
@@ -705,10 +642,11 @@ found:
* check for bypass sockets.
*/
if ((ip->ip_p == IPPROTO_TCP) || (ip->ip_p == IPPROTO_UDP))
- goto skipipsec2;
+ goto skipipsec;
/* IPsec policy check for local-delivery packets */
s = splnet();
+ tdbi = (struct tdb_ident *) m->m_pkthdr.tdbi;
if (tdbi == NULL)
tdb = NULL;
else
@@ -721,19 +659,11 @@ found:
/* Error or otherwise drop-packet indication */
if (error) {
ipstat.ips_cantforward++;
- if (tdbi)
- free(tdbi, M_TEMP);
m_freem(m);
return;
}
skipipsec:
- if (tdbi) {
- free(tdbi, M_TEMP);
- m->m_pkthdr.tdbi = NULL;
- }
-
- skipipsec2:
/* Otherwise, just fall through and deliver the packet */
#endif /* IPSEC */
@@ -744,10 +674,6 @@ found:
(*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen, NULL, 0);
return;
bad:
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
}
@@ -1319,6 +1245,8 @@ ip_weadvertise(addr)
if (rt == 0)
return 0;
+ RTFREE(rt);
+
if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
rt->rt_gateway->sa_family != AF_LINK) {
RTFREE(rt);
diff --git a/sys/netinet/ip_ipip.c b/sys/netinet/ip_ipip.c
index 38de7643246..2eb74ac7399 100644
--- a/sys/netinet/ip_ipip.c
+++ b/sys/netinet/ip_ipip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipip.c,v 1.10 2001/02/28 01:24:55 angelos Exp $ */
+/* $OpenBSD: ip_ipip.c,v 1.11 2001/03/28 20:03:04 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -87,8 +87,6 @@
#define offsetof(s, e) ((int)&((s *)0)->e)
#endif
-#define PI_MAGIC 0xdeadbeef /* XXX */
-
/*
* We can control the acceptance of IP4 packets by altering the sysctl
* net.inet.ipip.allow value. Zero means drop them, all else is acceptance.
@@ -104,18 +102,11 @@ struct ipipstat ipipstat;
int
ip4_input6(struct mbuf **m, int *offp, int proto)
{
- void *tdbi = (*m)->m_pkthdr.tdbi;
-
- if (tdbi == (void *) PI_MAGIC)
- tdbi = NULL;
-
/* If we do not accept IPv4 explicitly, drop. */
if (!ipip_allow && ((*m)->m_flags & (M_AUTH|M_CONF)) == 0)
{
DPRINTF(("ip4_input6(): dropped due to policy\n"));
ipipstat.ipips_pdrops++;
- if (tdbi)
- free(tdbi, M_TEMP);
m_freem(*m);
return IPPROTO_DONE;
}
@@ -134,18 +125,12 @@ ip4_input(struct mbuf *m, ...)
{
va_list ap;
int iphlen;
- void *tdbi = m->m_pkthdr.tdbi;
-
- if (tdbi == (void *) PI_MAGIC)
- tdbi = NULL;
/* If we do not accept IPv4 explicitly, drop. */
if (!ipip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0)
{
DPRINTF(("ip4_input(): dropped due to policy\n"));
ipipstat.ipips_pdrops++;
- if (tdbi)
- free(tdbi, M_TEMP);
m_freem(m);
return;
}
@@ -183,13 +168,9 @@ ipip_input(struct mbuf *m, int iphlen)
u_int8_t otos;
u_int8_t v;
int hlen, s;
- void *tdbi = m->m_pkthdr.tdbi;
ipipstat.ipips_ipackets++;
- if (tdbi == (void *) PI_MAGIC)
- tdbi = NULL;
-
m_copydata(m, 0, 1, &v);
switch (v >> 4)
@@ -206,8 +187,6 @@ ipip_input(struct mbuf *m, int iphlen)
break;
#endif
default:
- if (tdbi)
- free(tdbi, M_TEMP);
m_freem(m);
return /* EAFNOSUPPORT */;
}
@@ -219,8 +198,6 @@ ipip_input(struct mbuf *m, int iphlen)
{
DPRINTF(("ipip_input(): m_pullup() failed\n"));
ipipstat.ipips_hdrops++;
- if (tdbi)
- free(tdbi, M_TEMP);
return;
}
}
@@ -232,12 +209,6 @@ ipip_input(struct mbuf *m, int iphlen)
{
if (IN_MULTICAST(((struct ip *)((char *) ipo + iphlen))->ip_dst.s_addr))
{
- if (tdbi)
- {
- free(tdbi, M_TEMP);
- m->m_pkthdr.tdbi = NULL;
- }
-
ipip_mroute_input (m, iphlen);
return;
}
@@ -256,7 +227,7 @@ ipip_input(struct mbuf *m, int iphlen)
otos = (ntohl(mtod(m, struct ip6_hdr *)->ip6_flow) >> 20) & 0xff;
#endif
- /* Remove outter IP header */
+ /* Remove outer IP header */
m_adj(m, iphlen);
m_copydata(m, 0, 1, &v);
@@ -276,8 +247,6 @@ ipip_input(struct mbuf *m, int iphlen)
#endif
default:
- if (tdbi)
- free(tdbi, M_TEMP);
m_freem(m);
return /* EAFNOSUPPORT */;
}
@@ -288,8 +257,6 @@ ipip_input(struct mbuf *m, int iphlen)
if ((m = m_pullup(m, hlen)) == 0)
{
DPRINTF(("ipip_input(): m_pullup() failed\n"));
- if (tdbi)
- free(tdbi, M_TEMP);
ipipstat.ipips_hdrops++;
return;
}
@@ -347,8 +314,6 @@ ipip_input(struct mbuf *m, int iphlen)
{
DPRINTF(("ipip_input(): possible local address spoofing detected on packet from %s to %s (%s->%s)\n", inet_ntoa4(ipo->ip_src), inet_ntoa4(ipo->ip_dst), inet_ntoa4(ipo->ip_src), inet_ntoa4(ipo->ip_dst)));
ipipstat.ipips_spoof++;
- if (tdbi)
- free(tdbi, M_TEMP);
m_freem(m);
return;
}
@@ -366,8 +331,6 @@ ipip_input(struct mbuf *m, int iphlen)
if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src))
{
DPRINTF(("ipip_input(): possible local address spoofing detected on packet\n"));
- if (tdbi)
- free(tdbi, M_TEMP);
m_freem(m);
return;
}
@@ -410,8 +373,6 @@ ipip_input(struct mbuf *m, int iphlen)
{
IF_DROP(ifq);
m_freem(m);
- if (tdbi)
- free(tdbi, M_TEMP);
ipipstat.ipips_qfull++;
splx(s);
@@ -471,7 +432,7 @@ ipip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
*mp = NULL;
return ENOBUFS;
}
-
+
ipo = mtod(m, struct ip *);
ipo->ip_v = IPVERSION;
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index c4b83425334..b2859a46e74 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.110 2001/03/27 14:45:22 art Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.111 2001/03/28 20:03:04 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -319,13 +319,6 @@ gettdbbyaddr(union sockaddr_union *dst, u_int8_t proto, struct mbuf *m, int af)
if ((tdbp->tdb_srcid == NULL) && (tdbp->tdb_dstid == NULL))
break;
- /* We only grok addresses */
- if (((tdbp->tdb_srcid_type != SADB_IDENTTYPE_PREFIX) &&
- (tdbp->tdb_dstid_type != SADB_IDENTTYPE_CONNECTION)) ||
- ((tdbp->tdb_dstid_type != SADB_IDENTTYPE_PREFIX) &&
- (tdbp->tdb_dstid_type != SADB_IDENTTYPE_CONNECTION)))
- continue;
-
/* Sanity */
if ((m == NULL) || (af == 0))
continue;
@@ -364,13 +357,6 @@ gettdbbysrc(union sockaddr_union *src, u_int8_t proto, struct mbuf *m, int af)
if ((tdbp->tdb_srcid == NULL) && (tdbp->tdb_dstid == NULL))
break;
- /* We only grok addresses */
- if (((tdbp->tdb_srcid_type != SADB_IDENTTYPE_PREFIX) &&
- (tdbp->tdb_dstid_type != SADB_IDENTTYPE_CONNECTION)) ||
- ((tdbp->tdb_dstid_type != SADB_IDENTTYPE_PREFIX) &&
- (tdbp->tdb_dstid_type != SADB_IDENTTYPE_CONNECTION)))
- continue;
-
/* XXX Check the IDs ? */
break;
}
@@ -685,11 +671,18 @@ tdb_delete(struct tdb *tdbp)
}
/* Cleanup inp references */
- for (inp = TAILQ_FIRST(&tdbp->tdb_inp); inp;
- inp = TAILQ_FIRST(&tdbp->tdb_inp))
+ for (inp = TAILQ_FIRST(&tdbp->tdb_inp_in); inp;
+ inp = TAILQ_FIRST(&tdbp->tdb_inp_in))
+ {
+ TAILQ_REMOVE(&tdbp->tdb_inp_in, inp, inp_tdb_in_next);
+ inp->inp_tdb_in = NULL;
+ }
+
+ for (inp = TAILQ_FIRST(&tdbp->tdb_inp_out); inp;
+ inp = TAILQ_FIRST(&tdbp->tdb_inp_out))
{
- TAILQ_REMOVE(&tdbp->tdb_inp, inp, inp_tdb_next);
- inp->inp_tdb = NULL;
+ TAILQ_REMOVE(&tdbp->tdb_inp_out, inp, inp_tdb_out_next);
+ inp->inp_tdb_out = NULL;
}
/* Cleanup SPD references */
@@ -721,10 +714,16 @@ tdb_delete(struct tdb *tdbp)
tdbp->tdb_dstid = NULL;
}
- if (tdbp->tdb_credentials)
+ if (tdbp->tdb_src_credentials)
+ {
+ FREE(tdbp->tdb_src_credentials, M_XDATA);
+ tdbp->tdb_src_credentials = NULL;
+ }
+
+ if (tdbp->tdb_dst_credentials)
{
- FREE(tdbp->tdb_credentials, M_XDATA);
- tdbp->tdb_credentials = NULL;
+ FREE(tdbp->tdb_dst_credentials, M_XDATA);
+ tdbp->tdb_dst_credentials = NULL;
}
if ((tdbp->tdb_onext) && (tdbp->tdb_onext->tdb_inext == tdbp))
@@ -964,10 +963,6 @@ ipsp_kern(int off, char **bufp, int len)
ipsp_address(tdb->tdb_inext->tdb_dst),
tdb->tdb_inext->tdb_sproto);
- if (tdb->tdb_interface)
- l += sprintf(buffer + l, "\tAssociated interface = <%s>\n",
- ((struct ifnet *) tdb->tdb_interface)->if_xname);
-
l += sprintf(buffer + l, "\t%qu bytes processed by this SA\n",
tdb->tdb_cur_bytes);
@@ -1083,20 +1078,38 @@ get_sa_require(struct inpcb *inp)
* Add an inpcb to the list of inpcb which reference this tdb directly.
*/
void
-tdb_add_inp(struct tdb *tdb, struct inpcb *inp)
+tdb_add_inp(struct tdb *tdb, struct inpcb *inp, int inout)
{
- if (inp->inp_tdb)
+ if (inout)
{
- if (inp->inp_tdb == tdb)
- return;
+ if (inp->inp_tdb_in)
+ {
+ if (inp->inp_tdb_in == tdb)
+ return;
+
+ TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp, inp_tdb_in_next);
+ }
- TAILQ_REMOVE(&inp->inp_tdb->tdb_inp, inp, inp_tdb_next);
+ inp->inp_tdb_in = tdb;
+ TAILQ_INSERT_TAIL(&tdb->tdb_inp_in, inp, inp_tdb_in_next);
}
+ else
+ {
+ if (inp->inp_tdb_out)
+ {
+ if (inp->inp_tdb_out == tdb)
+ return;
+
+ TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp,
+ inp_tdb_out_next);
+ }
- inp->inp_tdb = tdb;
- TAILQ_INSERT_TAIL(&tdb->tdb_inp, inp, inp_tdb_next);
+ inp->inp_tdb_out = tdb;
+ TAILQ_INSERT_TAIL(&tdb->tdb_inp_out, inp, inp_tdb_out_next);
+ }
- DPRINTF(("tdb_add_inp: tdb: %p, inp: %p\n", tdb, inp));
+ DPRINTF(("tdb_add_inp: tdb: %p, inp: %p, direction: %s\n", tdb, inp,
+ inout ? "in" : "out"));
}
/* Return a printable string for the IPv4 address. */
@@ -1133,3 +1146,25 @@ ipsp_address(union sockaddr_union sa)
return "(unknown address family)";
}
}
+
+/* Copy a struct tdb_ident structure */
+void *
+ipsp_copy_ident(void *arg)
+{
+ struct tdb_ident *tdbii, *tdbi;
+
+ tdbi = (struct tdb_ident *) arg;
+
+ /*
+ * Allocate new structure. If we fail, just return NULL -- the
+ * new packet will be treated as if it was not protected.
+ */
+ MALLOC(tdbii, struct tdb_ident *, sizeof(struct tdb_ident), M_TEMP,
+ M_NOWAIT);
+ if (tdbii == NULL)
+ return NULL;
+ bcopy(&tdbi->dst, &tdbii->dst, sizeof(union sockaddr_union));
+ tdbii->proto = tdbi->proto;
+ tdbii->spi = tdbi->spi;
+ return (void *) tdbii;
+}
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index 78f4298868f..f7e2a713a09 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.81 2001/03/27 14:45:22 art Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.82 2001/03/28 20:03:04 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -294,11 +294,13 @@ struct tdb /* tunnel descriptor block */
u_int16_t tdb_amxkeylen; /* Raw authentication key length */
u_int16_t tdb_emxkeylen; /* Raw encryption key length */
u_int16_t tdb_ivlen; /* IV length */
- u_int16_t tdb_cred_len; /* size of tdb_credentials */
+ u_int16_t tdb_src_cred_len; /* size of tdb_src_credentials */
+ u_int16_t tdb_dst_cred_len; /* size of tdb_dst_credentials */
u_int8_t tdb_sproto; /* IPsec protocol */
u_int8_t tdb_wnd; /* Replay window */
u_int8_t tdb_satype; /* SA type (RFC2367, PF_KEY) */
- u_int8_t tdb_cred_type; /* type of tdb_credentials */
+ u_int8_t tdb_src_cred_type;/* type of tdb_src_credentials */
+ u_int8_t tdb_dst_cred_type;/* type of tdb_dst_credentials */
union sockaddr_union tdb_dst; /* Destination address for this SA */
union sockaddr_union tdb_src; /* Source address for this SA */
@@ -321,10 +323,11 @@ struct tdb /* tunnel descriptor block */
u_int8_t tdb_iv[4]; /* Used for HALF-IV ESP */
- caddr_t tdb_interface;
- caddr_t tdb_credentials;
+ caddr_t tdb_src_credentials;
+ caddr_t tdb_dst_credentials;
- TAILQ_HEAD(tdb_inp_head, inpcb) tdb_inp;
+ TAILQ_HEAD(tdb_inp_head_in, inpcb) tdb_inp_in;
+ TAILQ_HEAD(tdb_inp_head_out, inpcb) tdb_inp_out;
TAILQ_HEAD(tdb_policy_head, ipsec_policy) tdb_policy_head;
};
@@ -469,7 +472,7 @@ extern char *inet_ntoa4(struct in_addr);
extern char *ipsp_address(union sockaddr_union);
/* TDB management routines */
-extern void tdb_add_inp(struct tdb *tdb, struct inpcb *inp);
+extern void tdb_add_inp(struct tdb *, struct inpcb *, int);
extern u_int32_t reserve_spi(u_int32_t, u_int32_t, union sockaddr_union *,
union sockaddr_union *, u_int8_t, int *);
extern struct tdb *gettdb(u_int32_t, union sockaddr_union *, u_int8_t);
@@ -584,5 +587,6 @@ extern struct ipsec_acquire *ipsp_pending_acquire(union sockaddr_union *);
extern struct ipsec_acquire *ipsec_get_acquire(u_int32_t);
extern void ipsp_delete_acquire(struct ipsec_acquire *);
extern void ipsp_clear_acquire(struct tdb *);
+extern void *ipsp_copy_ident(void *);
#endif /* _KERNEL */
#endif /* _NETINET_IPSP_H_ */
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 9164fbb1d00..94fba169a40 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.86 2001/03/07 23:19:54 aaron Exp $ */
+/* $OpenBSD: ip_output.c,v 1.87 2001/03/28 20:03:04 angelos Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -180,9 +180,9 @@ ip_output(m0, va_alist)
* If the higher-level protocol has cached the SA to use, we
* can avoid the routing lookup if the source address is zero.
*/
- if (inp != NULL && inp->inp_tdb != NULL &&
+ if (inp != NULL && inp->inp_tdb_out != NULL &&
ip->ip_src.s_addr == INADDR_ANY) {
- tdb = inp->inp_tdb;
+ tdb = inp->inp_tdb_out;
if (tdb->tdb_src.sa.sa_family == AF_INET &&
tdb->tdb_src.sin.sin_addr.s_addr != INADDR_ANY) {
ip->ip_src.s_addr = tdb->tdb_src.sin.sin_addr.s_addr;
@@ -281,11 +281,11 @@ ip_output(m0, va_alist)
* Check if there was an outgoing SA bound to the flow
* from a transport protocol.
*/
- if (inp && inp->inp_tdb &&
- inp->inp_tdb->tdb_dst.sa.sa_family == AF_INET &&
- !bcmp(&inp->inp_tdb->tdb_dst.sin.sin_addr,
+ if (inp && inp->inp_tdb_out &&
+ inp->inp_tdb_out->tdb_dst.sa.sa_family == AF_INET &&
+ !bcmp(&inp->inp_tdb_out->tdb_dst.sin.sin_addr,
&ip->ip_dst, sizeof(ip->ip_dst)))
- tdb = inp->inp_tdb;
+ tdb = inp->inp_tdb_out;
else
tdb = ipsp_spd_lookup(m, AF_INET, hlen, &error,
IPSP_DIRECTION_OUT, NULL, inp);
@@ -550,12 +550,10 @@ sendit:
if (fr_checkp) {
/*
* Ok, it's time for a simple round-trip to the IPF/NAT
- * code with the enc# interface
+ * code with the enc0 interface
*/
struct mbuf *m0 = m;
- void *ifp = tdb->tdb_interface ?
- (void *)tdb->tdb_interface :
- (void *)&encif[0].sc_if;
+ void *ifp = (void *)&encif[0].sc_if;
if ((*fr_checkp)(ip, hlen, ifp, 1, &m0)) {
error = EHOSTUNREACH;
splx(s);
@@ -579,6 +577,10 @@ sendit:
goto done;
}
+ /* Latch to PCB */
+ if (inp)
+ tdb_add_inp(tdb, inp, 0);
+
/* Massage the IP header for use by the IPsec code */
ip->ip_len = htons((u_short) ip->ip_len);
ip->ip_off = htons((u_short) ip->ip_off);
diff --git a/sys/netinet/ip_spd.c b/sys/netinet/ip_spd.c
index 92c2c57dbe5..e5594943053 100644
--- a/sys/netinet/ip_spd.c
+++ b/sys/netinet/ip_spd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_spd.c,v 1.13 2001/03/15 22:43:03 bjc Exp $ */
+/* $OpenBSD: ip_spd.c,v 1.14 2001/03/28 20:03:06 angelos Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -94,7 +94,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
* If there are no flows in place, there's no point
* continuing with the SPD lookup.
*/
- if (!ipsec_in_use)
+ if (!ipsec_in_use && inp == NULL)
{
*error = 0;
return NULL;
@@ -406,11 +406,14 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
ipo_tdb_next);
ipo->ipo_tdb = NULL;
+ ipo->ipo_last_searched = 0;
/* Fall through to acquisition of TDB */
}
else
- return ipo->ipo_tdb; /* Cached entry is good, we're done */
+ {
+ return ipo->ipo_tdb; /* Cached entry is good, we're done */
+ }
}
/*
@@ -510,6 +513,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
{
TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next);
ipo->ipo_tdb = NULL;
+ ipo->ipo_last_searched = 0;
}
switch (ipo->ipo_type)
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c
index 65dd05c11ff..6f36319a611 100644
--- a/sys/netinet/ipsec_input.c
+++ b/sys/netinet/ipsec_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_input.c,v 1.33 2001/03/15 06:31:00 mickey Exp $ */
+/* $OpenBSD: ipsec_input.c,v 1.34 2001/03/28 20:03:06 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -77,8 +77,6 @@
#include "bpfilter.h"
-#define PI_MAGIC 0xdeadbeef /* XXX horror! */
-
int ipsec_common_input(struct mbuf *, int, int, int, int);
#ifdef ENCDEBUG
@@ -218,10 +216,7 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
* XXX The fragment conflicts with scoped nature of IPv6, so do it for
* only for IPv4 for now.
*/
- if (tdbp->tdb_interface)
- m->m_pkthdr.rcvif = (struct ifnet *) tdbp->tdb_interface;
- else
- m->m_pkthdr.rcvif = &encif[0].sc_if;
+ m->m_pkthdr.rcvif = &encif[0].sc_if;
}
/* Register first use, setup expiration timer */
@@ -286,7 +281,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
/* Fix IPv4 header */
if (tdbp->tdb_dst.sa.sa_family == AF_INET)
{
- if ((m = m_pullup(m, skip)) == 0)
+ if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == 0))
{
DPRINTF(("ipsec_common_input_cb(): processing failed for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst), ntohl(tdbp->tdb_spi)));
IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops);
@@ -373,7 +368,8 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
/* Fix IPv6 header */
if (af == INET6)
{
- if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0)
+ if ((m->m_len < sizeof(struct ip6_hdr)) &&
+ ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0))
{
DPRINTF(("ipsec_common_input_cb(): processing failed for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst), ntohl(tdbp->tdb_spi)));
IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops);
@@ -458,7 +454,8 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
* Record what we've done to the packet (under what SA it was
* processed).
*/
- if (m->m_pkthdr.tdbi && m->m_pkthdr.tdbi != (void *) PI_MAGIC)
+ /* XXX We need a better packets-attributes framework */
+ if (m->m_pkthdr.tdbi)
free(m->m_pkthdr.tdbi, M_TEMP);
MALLOC(m->m_pkthdr.tdbi, void *, sizeof(struct tdb_ident), M_TEMP,
@@ -489,10 +486,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
m->m_flags |= M_AUTH;
#if NBPFILTER > 0
- if (tdbp->tdb_interface)
- bpfif = (struct ifnet *) tdbp->tdb_interface;
- else
- bpfif = &encif[0].sc_if;
+ bpfif = &encif[0].sc_if;
if (bpfif->if_bpf)
{
/*
@@ -631,8 +625,6 @@ ah4_input_cb(struct mbuf *m, ...)
if (IF_QFULL(ifq))
{
IF_DROP(ifq);
- if (m->m_pkthdr.tdbi && m->m_pkthdr.tdbi != (void *) PI_MAGIC)
- free(m->m_pkthdr.tdbi, M_TEMP);
m_freem(m);
ahstat.ahs_qfull++;
@@ -673,8 +665,6 @@ esp4_input_cb(struct mbuf *m, ...)
if (IF_QFULL(ifq))
{
IF_DROP(ifq);
- if (m->m_pkthdr.tdbi && m->m_pkthdr.tdbi != (void *) PI_MAGIC)
- free(m->m_pkthdr.tdbi, M_TEMP);
m_freem(m);
espstat.esps_qfull++;
@@ -780,8 +770,6 @@ ah6_input_cb(struct mbuf *m, int off, int protoff)
return 0;
bad:
- if (m->m_pkthdr.tdbi && m->m_pkthdr.tdbi != (void *) PI_MAGIC)
- free(m->m_pkthdr.tdbi, M_TEMP);
m_freem(m);
return EINVAL;
}
diff --git a/sys/netinet/ipsec_output.c b/sys/netinet/ipsec_output.c
index 724a7b7ded5..2882091411c 100644
--- a/sys/netinet/ipsec_output.c
+++ b/sys/netinet/ipsec_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_output.c,v 1.3 2001/03/15 06:31:00 mickey Exp $ */
+/* $OpenBSD: ipsec_output.c,v 1.4 2001/03/28 20:03:06 angelos Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -193,8 +193,9 @@ ipsp_process_packet(struct mbuf *m, struct tdb *tdb, int af, int tunalready)
/* Fix IPv4 header checksum and length */
if (af == AF_INET)
{
- if ((m = m_pullup(m, sizeof(struct ip))) == 0)
- return ENOBUFS;
+ if (m->m_len < sizeof(struct ip))
+ if ((m = m_pullup(m, sizeof(struct ip))) == 0)
+ return ENOBUFS;
ip = mtod(m, struct ip *);
ip->ip_len = htons(m->m_pkthdr.len);
@@ -207,7 +208,8 @@ ipsp_process_packet(struct mbuf *m, struct tdb *tdb, int af, int tunalready)
/* Fix IPv6 header payload length */
if (af == AF_INET6)
{
- if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0)
+ if (m->m_len < sizeof(struct ip6_hdr))
+ if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0)
return ENOBUFS;
if (m->m_pkthdr.len - sizeof(*ip6) > IPV6_MAXPACKET) {
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 922ece4df0e..98c64f08210 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.82 2001/02/08 18:46:22 itojun Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.83 2001/03/28 20:03:07 angelos Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -82,8 +82,6 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
#include <netinet/ip_ipsp.h>
#endif /* IPSEC */
-#define PI_MAGIC 0xdeadbeef /* XXX the horror! */
-
#ifdef INET6
#include <netinet6/in6_var.h>
#include <netinet/ip6.h>
@@ -400,12 +398,6 @@ tcp_input(m, va_alist)
#endif /* IPSEC */
int af;
-#ifdef IPSEC
- tdbi = (struct tdb_ident *) m->m_pkthdr.tdbi;
- if (tdbi == (void *) PI_MAGIC)
- tdbi = NULL;
-#endif /* IPSEC */
-
va_start(ap, m);
iphlen = va_arg(ap, int);
va_end(ap);
@@ -426,10 +418,6 @@ tcp_input(m, va_alist)
af = AF_INET;
break;
default:
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
return; /*EAFNOSUPPORT*/
}
@@ -442,10 +430,6 @@ tcp_input(m, va_alist)
case AF_INET:
#ifdef DIAGNOSTIC
if (iphlen < sizeof(struct ip)) {
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
return;
}
@@ -456,10 +440,6 @@ tcp_input(m, va_alist)
iphlen = sizeof(struct ip);
#else
printf("extension headers are not allowed\n");
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
return;
#endif
@@ -470,10 +450,6 @@ tcp_input(m, va_alist)
#ifdef DIAGNOSTIC
if (iphlen < sizeof(struct ip6_hdr)) {
m_freem(m);
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
#endif /* DIAGNOSTIC */
@@ -483,10 +459,6 @@ tcp_input(m, va_alist)
iphlen = sizeof(struct ip6_hdr);
#else
printf("extension headers are not allowed\n");
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
return;
#endif
@@ -494,10 +466,6 @@ tcp_input(m, va_alist)
break;
#endif
default:
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
return;
}
@@ -506,10 +474,6 @@ tcp_input(m, va_alist)
m = m_pullup2(m, iphlen + sizeof(struct tcphdr));
if (m == 0) {
tcpstat.tcps_rcvshort++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
}
@@ -597,10 +561,6 @@ tcp_input(m, va_alist)
if (m->m_len < iphlen + off) {
if ((m = m_pullup2(m, iphlen + off)) == 0) {
tcpstat.tcps_rcvshort++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
switch (af) {
@@ -801,14 +761,14 @@ findpcb:
tp = intotcpcb(inp);
tp->t_state = TCPS_LISTEN;
- /* Compute proper scaling value from buffer space
- */
+ /* Compute proper scaling value from buffer space */
tcp_rscale(tp, so->so_rcv.sb_hiwat);
}
}
#ifdef IPSEC
s = splnet();
+ tdbi = (struct tdb_ident *) m->m_pkthdr.tdbi;
if (tdbi == NULL)
tdb = NULL;
else
@@ -816,11 +776,18 @@ findpcb:
ipsp_spd_lookup(m, af, iphlen, &error, IPSP_DIRECTION_IN,
tdb, inp);
- splx(s);
- if (tdbi)
- free(tdbi, M_TEMP);
- tdbi = NULL;
+ /* Latch SA */
+ if (inp->inp_tdb_in != tdb) {
+ if (tdb)
+ tdb_add_inp(tdb, inp, 1);
+ else { /* Just reset */
+ TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp,
+ inp_tdb_in_next);
+ inp->inp_tdb_in = NULL;
+ }
+ }
+ splx(s);
/* Error or otherwise drop-packet indication */
if (error)
@@ -2118,11 +2085,6 @@ dropwithreset:
return;
drop:
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif
-
/*
* Drop space held by incoming segment and return.
*/
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 6f31222a7b0..da11deee254 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.55 2001/03/06 18:34:17 aaron Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.56 2001/03/28 20:03:07 angelos Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -94,8 +94,6 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
extern int ip6_defhlim;
#endif /* INET6 */
-#define PI_MAGIC 0xdeadbeef /* XXX the horror! */
-
/*
* UDP protocol implementation.
* Per RFC 768, August, 1980.
@@ -177,10 +175,6 @@ udp_input(m, va_alist)
struct tdb_ident *tdbi;
struct tdb *tdb;
int error, s;
-
- tdbi = (struct tdb_ident *) m->m_pkthdr.tdbi;
- if (tdbi == (void *) PI_MAGIC)
- tdbi = NULL;
#endif /* IPSEC */
va_start(ap, m);
@@ -231,10 +225,6 @@ udp_input(m, va_alist)
if (m->m_len < iphlen + sizeof(struct udphdr)) {
if ((m = m_pullup2(m, iphlen + sizeof(struct udphdr))) == 0) {
udpstat.udps_hdrops++;
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
#ifdef INET6
@@ -303,10 +293,6 @@ udp_input(m, va_alist)
if ((uh->uh_sum = in_cksum(m, len + sizeof (struct ip))) != 0) {
udpstat.udps_badsum++;
m_freem(m);
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
} else
@@ -480,10 +466,6 @@ udp_input(m, va_alist)
goto bad;
}
sorwakeup(last);
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
/*
@@ -528,19 +510,12 @@ udp_input(m, va_alist)
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT,
0, 0);
}
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
return;
}
}
#ifdef IPSEC
-#define PI_MAGIC 0xdeadbeef /* XXX the horror! */
tdbi = (struct tdb_ident *) m->m_pkthdr.tdbi;
- if (tdbi == (void *) PI_MAGIC)
- tdbi = NULL;
s = splnet();
if (tdbi == NULL)
@@ -552,9 +527,7 @@ udp_input(m, va_alist)
IPSP_DIRECTION_IN, tdb, inp);
splx(s);
- if (tdbi)
- free(tdbi, M_TEMP);
- tdbi = NULL;
+ /* No SA latching done for UDP */
/* Error or otherwise drop-packet indication */
if (error)
@@ -602,10 +575,6 @@ udp_input(m, va_alist)
sorwakeup(inp->inp_socket);
return;
bad:
-#ifdef IPSEC
- if (tdbi)
- free(tdbi, M_TEMP);
-#endif /* IPSEC */
m_freem(m);
if (opts)
m_freem(opts);
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 460eb8ef438..ab45ffb91b5 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: icmp6.c,v 1.36 2001/03/21 15:01:08 itojun Exp $ */
+/* $OpenBSD: icmp6.c,v 1.37 2001/03/28 20:03:07 angelos Exp $ */
/* $KAME: icmp6.c,v 1.205 2001/03/21 07:48:57 itojun Exp $ */
/*
@@ -625,6 +625,7 @@ icmp6_input(mp, offp, proto)
n->m_pkthdr.len += n0->m_pkthdr.len;
n->m_next = n0;
n0->m_flags &= ~M_PKTHDR;
+ n0->m_pkthdr.tdbi = NULL;
} else {
nip6 = mtod(n, struct ip6_hdr *);
nicmp6 = (struct icmp6_hdr *)((caddr_t)nip6 + off);
@@ -740,7 +741,7 @@ icmp6_input(mp, offp, proto)
bzero(p, 4);
bcopy(hostname, p + 4, maxhlen); /*meaningless TTL*/
noff = sizeof(struct ip6_hdr);
- M_COPY_PKTHDR(n, m); /* just for recvif */
+ M_DUP_PKTHDR(n, m); /* just for rcvif */
n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
sizeof(struct icmp6_hdr) + 4 + maxhlen;
nicmp6->icmp6_type = ICMP6_WRUREPLY;
@@ -1434,7 +1435,7 @@ ni6_input(m, off)
m_freem(m);
return(NULL);
}
- M_COPY_PKTHDR(n, m); /* just for recvif */
+ M_DUP_PKTHDR(n, m); /* just for rcvif */
if (replylen > MHLEN) {
if (replylen > MCLBYTES) {
/*
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index c966a3fc14f..d91c001a266 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_output.c,v 1.28 2001/03/25 09:56:00 itojun Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.29 2001/03/28 20:03:08 angelos Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -211,11 +211,11 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
* from a transport protocol.
*/
ip6 = mtod(m, struct ip6_hdr *);
- if (inp && inp->inp_tdb &&
- inp->inp_tdb->tdb_dst.sa.sa_family == AF_INET6 &&
- IN6_ARE_ADDR_EQUAL(&inp->inp_tdb->tdb_dst.sin6.sin6_addr,
+ if (inp && inp->inp_tdb_out &&
+ inp->inp_tdb_out->tdb_dst.sa.sa_family == AF_INET6 &&
+ IN6_ARE_ADDR_EQUAL(&inp->inp_tdb_out->tdb_dst.sin6.sin6_addr,
&ip6->ip6_dst)) {
- tdb = inp->inp_tdb;
+ tdb = inp->inp_tdb_out;
} else {
tdb = ipsp_spd_lookup(m, AF_INET6, sizeof(struct ip6_hdr),
&error, IPSP_DIRECTION_OUT, NULL, NULL);
@@ -587,6 +587,10 @@ skip_ipsec2:;
goto done;
}
+ /* Latch to PCB */
+ if (inp)
+ tdb_add_inp(tdb, inp, 0);
+
m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
/* Callee frees mbuf */
@@ -1435,11 +1439,11 @@ ip6_ctloutput(op, so, level, optname, mp)
} else {
tdbip = mtod(m, struct tdb_ident *);
tdb = gettdb(tdbip->spi, &tdbip->dst,
- tdbip->proto);
+ tdbip->proto);
if (tdb == NULL)
error = ESRCH;
else
- tdb_add_inp(tdb, inp);
+ tdb_add_inp(tdb, inp, 0);
}
splx(s);
#endif /* IPSEC */
@@ -1647,12 +1651,12 @@ ip6_ctloutput(op, so, level, optname, mp)
error = EINVAL;
#else
s = spltdb();
- if (inp->inp_tdb == NULL) {
+ if (inp->inp_tdb_out == NULL) {
error = ENOENT;
} else {
- tdbi.spi = inp->inp_tdb->tdb_spi;
- tdbi.dst = inp->inp_tdb->tdb_dst;
- tdbi.proto = inp->inp_tdb->tdb_sproto;
+ tdbi.spi = inp->inp_tdb_out->tdb_spi;
+ tdbi.dst = inp->inp_tdb_out->tdb_dst;
+ tdbi.proto = inp->inp_tdb_out->tdb_sproto;
*mp = m = m_get(M_WAIT, MT_SOOPTS);
m->m_len = sizeof(tdbi);
bcopy((caddr_t)&tdbi, mtod(m, caddr_t),
@@ -2341,6 +2345,7 @@ ip6_splithdr(m, exthdrs)
M_COPY_PKTHDR(mh, m);
MH_ALIGN(mh, sizeof(*ip6));
m->m_flags &= ~M_PKTHDR;
+ m->m_pkthdr.tdbi = NULL;
m->m_len -= sizeof(*ip6);
m->m_data += sizeof(*ip6);
mh->m_next = m;
diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c
index a668b5ddb3c..2d8433eed5e 100644
--- a/sys/nfs/nfs_socket.c
+++ b/sys/nfs/nfs_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_socket.c,v 1.19 2000/08/10 16:28:42 deraadt Exp $ */
+/* $OpenBSD: nfs_socket.c,v 1.20 2001/03/28 20:03:08 angelos Exp $ */
/* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */
/*
@@ -1515,6 +1515,11 @@ nfs_realign(m, hsiz)
olen = m->m_len;
fcp = mtod(m, caddr_t);
if ((long)fcp & 0x3) {
+ if (m->m_flags & M_PKTHDR) {
+ if (m->m_pkthdr.tdbi) /* XXX */
+ free(m->m_pkthdr.tdbi, M_TEMP);
+ m->m_pkthdr.tdbi = NULL;
+ }
m->m_flags &= ~M_PKTHDR;
if (m->m_flags & M_EXT)
m->m_data = m->m_ext.ext_buf +
@@ -1541,6 +1546,13 @@ nfs_realign(m, hsiz)
while (m) {
while (olen > 0) {
if (mlen == 0) {
+ if (m2->m_flags & M_PKTHDR) {
+ /* XXX */
+ if (m2->m_pkthdr.tdbi)
+ free(m2->m_pkthdr.tdbi,
+ M_TEMP);
+ m2->m_pkthdr.tdbi = NULL;
+ }
m2->m_flags &= ~M_PKTHDR;
if (m2->m_flags & M_EXT)
m2->m_data = m2->m_ext.ext_buf;
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 936c2f759aa..75cb34a945e 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbuf.h,v 1.20 2001/03/18 18:51:10 aaron Exp $ */
+/* $OpenBSD: mbuf.h,v 1.21 2001/03/28 20:03:09 angelos Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
@@ -40,6 +40,8 @@
#include <sys/malloc.h>
#endif
+extern void *ipsp_copy_ident(void *);
+
/*
* Mbufs are of a single size, MSIZE (machine/param.h), which
* includes overhead. An mbuf may add a single "mbuf cluster" of size
@@ -293,16 +295,48 @@ union mcluster {
else \
MCLFREE((m)->m_ext.ext_buf); \
} \
+ if (((m)->m_flags & M_PKTHDR) && ((m)->m_pkthdr.tdbi)) { \
+ free((m)->m_pkthdr.tdbi, M_TEMP); \
+ (m)->m_pkthdr.tdbi = NULL; \
+ } \
(n) = (m)->m_next; \
FREE((m), mbtypes[(m)->m_type]); \
}
/*
+ * Copy just m_pkthdr from from to to.
+ */
+#define M_COPY_HDR(to, from) { \
+ (to)->m_pkthdr = (from)->m_pkthdr; \
+}
+
+/*
+ * Duplicate just m_pkthdr from from to to.
+ * XXX Deal with a generic packet attribute framework.
+ */
+#define M_DUP_HDR(to, from) { \
+ M_COPY_HDR((to), (from)); \
+ if ((from)->m_pkthdr.tdbi) { \
+ (to)->m_pkthdr.tdbi = ipsp_copy_ident((from)->m_pkthdr.tdbi); \
+ } \
+}
+
+/*
+ * Duplicate mbuf pkthdr from from to to.
+ * from must have M_PKTHDR set, and to must be empty.
+ */
+#define M_DUP_PKTHDR(to, from) { \
+ M_DUP_HDR((to), (from)); \
+ (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
+ (to)->m_data = (to)->m_pktdat; \
+}
+
+/*
* Copy mbuf pkthdr from from to to.
* from must have M_PKTHDR set, and to must be empty.
*/
#define M_COPY_PKTHDR(to, from) { \
- (to)->m_pkthdr = (from)->m_pkthdr; \
+ M_COPY_HDR((to), (from)); \
(to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
(to)->m_data = (to)->m_pktdat; \
}