Page MenuHomeFreeBSD

D48265.id148675.diff
No OneTemporary

D48265.id148675.diff

diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -936,8 +936,8 @@
mb_free_extpg(old_m);
}
-static struct mbuf *
-_mb_unmapped_to_ext(struct mbuf *m)
+static int
+_mb_unmapped_to_ext(struct mbuf *m, struct mbuf **mres)
{
struct mbuf *m_new, *top, *prev, *mref;
struct sf_buf *sf;
@@ -947,9 +947,15 @@
u_int ref_inc = 0;
M_ASSERTEXTPG(m);
+
+ if (m->m_epg_tls != NULL) {
+ /* can't convert TLS mbuf */
+ m_freem(m);
+ *mres = NULL;
+ return (EINVAL);
+ }
+
len = m->m_len;
- KASSERT(m->m_epg_tls == NULL, ("%s: can't convert TLS mbuf %p",
- __func__, m));
/* See if this is the mbuf that holds the embedded refcount. */
if (m->m_ext.ext_flags & EXT_FLAG_EMBREF) {
@@ -1048,7 +1054,8 @@
atomic_add_int(refcnt, ref_inc);
}
m_free(m);
- return (top);
+ *mres = top;
+ return (0);
fail:
if (ref_inc != 0) {
@@ -1065,13 +1072,15 @@
}
m_free(m);
m_freem(top);
- return (NULL);
+ *mres = NULL;
+ return (ENOMEM);
}
-struct mbuf *
-mb_unmapped_to_ext(struct mbuf *top)
+int
+mb_unmapped_to_ext(struct mbuf *top, struct mbuf **mres)
{
- struct mbuf *m, *next, *prev = NULL;
+ struct mbuf *m, *m1, *next, *prev = NULL;
+ int error;
prev = NULL;
for (m = top; m != NULL; m = next) {
@@ -1087,12 +1096,15 @@
*/
prev->m_next = NULL;
}
- m = _mb_unmapped_to_ext(m);
- if (m == NULL) {
- m_freem(top);
+ error = _mb_unmapped_to_ext(m, &m1);
+ if (error != 0) {
+ if (top != m)
+ m_free(top);
m_freem(next);
- return (NULL);
+ *mres = NULL;
+ return (error);
}
+ m = m1;
if (prev == NULL) {
top = m;
} else {
@@ -1111,7 +1123,8 @@
prev = m;
}
}
- return (top);
+ *mres = top;
+ return (0);
}
/*
diff --git a/sys/net/if_ipsec.c b/sys/net/if_ipsec.c
--- a/sys/net/if_ipsec.c
+++ b/sys/net/if_ipsec.c
@@ -353,7 +353,7 @@
IPSEC_RLOCK_TRACKER;
struct ipsec_softc *sc;
struct secpolicy *sp;
- struct ip *ip;
+ struct ip *ip, iph;
uint32_t af;
int error;
@@ -375,7 +375,8 @@
}
/* Determine address family to correctly handle packet in BPF */
- ip = mtod(m, struct ip *);
+ ip = &iph;
+ m_copydata(m, 0, sizeof(*ip), (char *)ip);
switch (ip->ip_v) {
#ifdef INET
case IPVERSION:
@@ -415,7 +416,8 @@
switch (af) {
#ifdef INET
case AF_INET:
- error = ipsec4_process_packet(ifp, m, sp, NULL, ifp->if_mtu);
+ error = ipsec4_process_packet(ifp, m, ip, sp, NULL,
+ ifp->if_mtu);
break;
#endif
#ifdef INET6
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -667,18 +667,19 @@
sendit:
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
if (IPSEC_ENABLED(ipv4)) {
- m = mb_unmapped_to_ext(m);
- if (m == NULL) {
- IPSTAT_INC(ips_odropped);
- error = ENOBUFS;
- goto bad;
- }
+ struct ip ip_hdr;
+
if ((error = IPSEC_OUTPUT(ipv4, ifp, m, inp, mtu)) != 0) {
if (error == EINPROGRESS)
error = 0;
goto done;
}
+
+ /* Update variables that are affected by ipsec4_output(). */
+ m_copydata(m, 0, sizeof(ip_hdr), (char *)&ip_hdr);
+ hlen = ip_hdr.ip_hl << 2;
}
+
/*
* Check if there was a route for this packet; return error if not.
*/
@@ -687,9 +688,6 @@
error = EHOSTUNREACH;
goto bad;
}
- /* Update variables that are affected by ipsec4_output(). */
- ip = mtod(m, struct ip *);
- hlen = ip->ip_hl << 2;
#endif /* IPSEC */
/* Jump over all PFIL processing if hooks are not active. */
@@ -731,11 +729,20 @@
/* Ensure the packet data is mapped if the interface requires it. */
if ((ifp->if_capenable & IFCAP_MEXTPG) == 0) {
- m = mb_unmapped_to_ext(m);
- if (m == NULL) {
+ struct mbuf *m1;
+
+ error = mb_unmapped_to_ext(m, &m1);
+ if (error != 0) {
+ if (error == EINVAL) {
+ if_printf(ifp, "TLS packet\n");
+ /* XXXKIB */
+ } else if (error == ENOMEM) {
+ error = ENOBUFS;
+ }
IPSTAT_INC(ips_odropped);
- error = ENOBUFS;
goto bad;
+ } else {
+ m = m1;
}
}
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -792,12 +792,6 @@
* XXX: need scope argument.
*/
if (IPSEC_ENABLED(ipv6)) {
- m = mb_unmapped_to_ext(m);
- if (m == NULL) {
- IP6STAT_INC(ip6s_odropped);
- error = ENOBUFS;
- goto bad;
- }
if ((error = IPSEC_OUTPUT(ipv6, ifp, m, inp, mtu == 0 ?
ifp->if_mtu : mtu)) != 0) {
if (error == EINPROGRESS)
@@ -1106,10 +1100,20 @@
/* Ensure the packet data is mapped if the interface requires it. */
if ((ifp->if_capenable & IFCAP_MEXTPG) == 0) {
- m = mb_unmapped_to_ext(m);
- if (m == NULL) {
+ struct mbuf *m1;
+
+ error = mb_unmapped_to_ext(m, &m1);
+ if (error != 0) {
+ if (error == EINVAL) {
+ if_printf(ifp, "TLS packet\n");
+ /* XXXKIB */
+ } else if (error == ENOMEM) {
+ error = ENOBUFS;
+ }
IP6STAT_INC(ip6s_odropped);
- return (ENOBUFS);
+ return (error);
+ } else {
+ m = m1;
}
}
diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h
--- a/sys/netipsec/ipsec.h
+++ b/sys/netipsec/ipsec.h
@@ -325,6 +325,7 @@
#endif
struct inpcb;
+struct ip;
struct m_tag;
struct secasvar;
struct sockopt;
@@ -336,7 +337,7 @@
struct ipsecrequest *ipsec_newisr(void);
void ipsec_delisr(struct ipsecrequest *);
struct secpolicy *ipsec4_checkpolicy(const struct mbuf *, struct inpcb *,
- int *, int);
+ struct ip *, int *, int);
u_int ipsec_get_reqlevel(struct secpolicy *, u_int);
@@ -351,12 +352,13 @@
void ipsec_setspidx_inpcb(struct inpcb *, struct secpolicyindex *, u_int);
-void ipsec4_setsockaddrs(const struct mbuf *, union sockaddr_union *,
- union sockaddr_union *);
+void ipsec4_setsockaddrs(const struct mbuf *, const struct ip *,
+ union sockaddr_union *, union sockaddr_union *);
int ipsec4_common_input_cb(struct mbuf *, struct secasvar *, int, int);
-int ipsec4_check_pmtu(struct ifnet *, struct mbuf *, struct secpolicy *, int);
-int ipsec4_process_packet(struct ifnet *, struct mbuf *, struct secpolicy *,
- struct inpcb *, u_long);
+int ipsec4_check_pmtu(struct ifnet *, struct mbuf *, struct ip *ip1,
+ struct secpolicy *, int);
+int ipsec4_process_packet(struct ifnet *, struct mbuf *, struct ip *ip1,
+ struct secpolicy *, struct inpcb *, u_long);
int ipsec_process_done(struct mbuf *, struct secpolicy *, struct secasvar *,
u_int);
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -286,8 +286,9 @@
const struct mbuf *);
#ifdef INET
-static void ipsec4_get_ulp(const struct mbuf *, struct secpolicyindex *, int);
-static void ipsec4_setspidx_ipaddr(const struct mbuf *,
+static void ipsec4_get_ulp(const struct mbuf *, const struct ip *,
+ struct secpolicyindex *, int);
+static void ipsec4_setspidx_ipaddr(const struct mbuf *, struct ip *,
struct secpolicyindex *);
#endif
#ifdef INET6
@@ -488,8 +489,8 @@
#ifdef INET
static void
-ipsec4_get_ulp(const struct mbuf *m, struct secpolicyindex *spidx,
- int needport)
+ipsec4_get_ulp(const struct mbuf *m, const struct ip *ip1,
+ struct secpolicyindex *spidx, int needport)
{
uint8_t nxt;
int off;
@@ -498,21 +499,10 @@
IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),
("packet too short"));
- if (m->m_len >= sizeof (struct ip)) {
- const struct ip *ip = mtod(m, const struct ip *);
- if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
- goto done;
- off = ip->ip_hl << 2;
- nxt = ip->ip_p;
- } else {
- struct ip ih;
-
- m_copydata(m, 0, sizeof (struct ip), (caddr_t) &ih);
- if (ih.ip_off & htons(IP_MF | IP_OFFMASK))
- goto done;
- off = ih.ip_hl << 2;
- nxt = ih.ip_p;
- }
+ if (ip1->ip_off & htons(IP_MF | IP_OFFMASK))
+ goto done;
+ off = ip1->ip_hl << 2;
+ nxt = ip1->ip_p;
while (off < m->m_pkthdr.len) {
struct ip6_ext ip6e;
@@ -565,17 +555,18 @@
}
static void
-ipsec4_setspidx_ipaddr(const struct mbuf *m, struct secpolicyindex *spidx)
+ipsec4_setspidx_ipaddr(const struct mbuf *m, struct ip *ip1,
+ struct secpolicyindex *spidx)
{
- ipsec4_setsockaddrs(m, &spidx->src, &spidx->dst);
+ ipsec4_setsockaddrs(m, ip1, &spidx->src, &spidx->dst);
spidx->prefs = sizeof(struct in_addr) << 3;
spidx->prefd = sizeof(struct in_addr) << 3;
}
static struct secpolicy *
-ipsec4_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir,
- int needport)
+ipsec4_getpolicy(const struct mbuf *m, struct inpcb *inp, struct ip *ip1,
+ u_int dir, int needport)
{
struct secpolicyindex spidx;
struct secpolicy *sp;
@@ -583,8 +574,8 @@
sp = ipsec_getpcbpolicy(inp, dir);
if (sp == NULL && key_havesp(dir)) {
/* Make an index to look for a policy. */
- ipsec4_setspidx_ipaddr(m, &spidx);
- ipsec4_get_ulp(m, &spidx, needport);
+ ipsec4_setspidx_ipaddr(m, ip1, &spidx);
+ ipsec4_get_ulp(m, ip1, &spidx, needport);
spidx.dir = dir;
sp = key_allocsp(&spidx, dir);
}
@@ -597,13 +588,13 @@
* Check security policy for *OUTBOUND* IPv4 packet.
*/
struct secpolicy *
-ipsec4_checkpolicy(const struct mbuf *m, struct inpcb *inp, int *error,
- int needport)
+ipsec4_checkpolicy(const struct mbuf *m, struct inpcb *inp, struct ip *ip1,
+ int *error, int needport)
{
struct secpolicy *sp;
*error = 0;
- sp = ipsec4_getpolicy(m, inp, IPSEC_DIR_OUTBOUND, needport);
+ sp = ipsec4_getpolicy(m, inp, ip1, IPSEC_DIR_OUTBOUND, needport);
if (sp != NULL)
sp = ipsec_checkpolicy(sp, inp, error);
if (sp == NULL) {
@@ -630,12 +621,13 @@
* rip_input() and sctp_input().
*/
int
-ipsec4_in_reject(const struct mbuf *m, struct inpcb *inp)
+ipsec4_in_reject1(const struct mbuf *m, struct ip *ip1, struct inpcb *inp)
{
struct secpolicy *sp;
#ifdef IPSEC_OFFLOAD
struct ipsec_accel_in_tag *tag;
#endif
+ struct ip ip_hdr;
int result;
#ifdef IPSEC_OFFLOAD
@@ -643,7 +635,13 @@
if (tag != NULL)
return (0);
#endif
- sp = ipsec4_getpolicy(m, inp, IPSEC_DIR_INBOUND, 0);
+
+ if (ip1 == NULL) {
+ ip1 = &ip_hdr;
+ m_copydata(m, 0, sizeof(*ip1), (char *)ip1);
+ }
+
+ sp = ipsec4_getpolicy(m, inp, ip1, IPSEC_DIR_INBOUND, 0);
result = ipsec_in_reject(sp, inp, m);
key_freesp(&sp);
if (result != 0)
@@ -651,6 +649,12 @@
return (result);
}
+int
+ipsec4_in_reject(const struct mbuf *m, struct inpcb *inp)
+{
+ return (ipsec4_in_reject1(m, NULL, inp));
+}
+
/*
* IPSEC_CAP() method implementation for IPv4.
*/
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -111,14 +111,13 @@
#ifdef INET
static struct secasvar *
-ipsec4_allocsa(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
- u_int *pidx, int *error)
+ipsec4_allocsa(struct ifnet *ifp, struct mbuf *m, const struct ip *ip,
+ struct secpolicy *sp, u_int *pidx, int *error)
{
struct secasindex *saidx, tmpsaidx;
struct ipsecrequest *isr;
struct sockaddr_in *sin;
struct secasvar *sav;
- struct ip *ip;
/*
* Check system global policy controls.
@@ -142,7 +141,6 @@
if (isr->saidx.mode == IPSEC_MODE_TRANSPORT) {
saidx = &tmpsaidx;
*saidx = isr->saidx;
- ip = mtod(m, struct ip *);
if (saidx->src.sa.sa_len == 0) {
sin = &saidx->src.sin;
sin->sin_len = sizeof(*sin);
@@ -188,13 +186,14 @@
* IPsec output logic for IPv4.
*/
static int
-ipsec4_perform_request(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
- struct inpcb *inp, u_int idx, u_long mtu)
+ipsec4_perform_request(struct ifnet *ifp, struct mbuf *m, struct ip *ip1,
+ struct secpolicy *sp, struct inpcb *inp, u_int idx, u_long mtu)
{
struct ipsec_ctx_data ctx;
union sockaddr_union *dst;
struct secasvar *sav;
struct ip *ip;
+ struct mbuf *m1;
int error, hwassist, i, off;
bool accel;
@@ -209,7 +208,7 @@
* determine next transform. At the end of transform we can
* release reference to SP.
*/
- sav = ipsec4_allocsa(ifp, m, sp, &idx, &error);
+ sav = ipsec4_allocsa(ifp, m, ip1, sp, &idx, &error);
if (sav == NULL) {
if (error == EJUSTRETURN) { /* No IPsec required */
(void)ipsec_accel_output(ifp, m, inp, sp, NULL,
@@ -225,6 +224,8 @@
IPSEC_INIT_CTX(&ctx, &m, inp, sav, AF_INET, IPSEC_ENC_BEFORE);
if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_OUT)) != 0)
goto bad;
+ /* Re-calculate *ip1 after potential change of m in the hook. */
+ m_copydata(m, 0, sizeof(*ip1), (char *)ip1);
hwassist = 0;
accel = ipsec_accel_output(ifp, m, inp, sp, sav, AF_INET, mtu,
@@ -240,16 +241,23 @@
}
#if defined(SCTP) || defined(SCTP_SUPPORT)
if ((m->m_pkthdr.csum_flags & CSUM_SCTP & ~hwassist) != 0) {
- struct ip *ip;
-
- ip = mtod(m, struct ip *);
- sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
+ sctp_delayed_cksum(m, (uint32_t)(ip1->ip_hl << 2));
m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
}
#endif
if (accel)
return (EJUSTRETURN);
+ error = mb_unmapped_to_ext(m, &m1);
+ if (error != 0) {
+ if (error == EINVAL) {
+ if (bootverbose)
+ if_printf(ifp, "Tx TLS+IPSEC packet\n");
+ }
+ return (error);
+ }
+ m = m1;
+
ip = mtod(m, struct ip *);
dst = &sav->sah->saidx.dst;
/* Do the appropriate encapsulation, if necessary */
@@ -317,19 +325,18 @@
}
int
-ipsec4_process_packet(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
- struct inpcb *inp, u_long mtu)
+ipsec4_process_packet(struct ifnet *ifp, struct mbuf *m, struct ip *ip1,
+ struct secpolicy *sp, struct inpcb *inp, u_long mtu)
{
- return (ipsec4_perform_request(ifp, m, sp, inp, 0, mtu));
+ return (ipsec4_perform_request(ifp, m, ip1, sp, inp, 0, mtu));
}
int
-ipsec4_check_pmtu(struct ifnet *ifp, struct mbuf *m, struct secpolicy *sp,
- int forwarding)
+ipsec4_check_pmtu(struct ifnet *ifp, struct mbuf *m, struct ip *ip1,
+ struct secpolicy *sp, int forwarding)
{
struct secasvar *sav;
- struct ip *ip;
size_t hlen, pmtu;
uint32_t idx;
int error;
@@ -341,13 +348,12 @@
goto setdf;
/* V_ip4_ipsec_dfbit > 1 - we will copy it from inner header. */
- ip = mtod(m, struct ip *);
- if (!(ip->ip_off & htons(IP_DF)))
+ if ((ip1->ip_off & htons(IP_DF)) == 0)
return (0);
setdf:
idx = sp->tcount - 1;
- sav = ipsec4_allocsa(ifp, m, sp, &idx, &error);
+ sav = ipsec4_allocsa(ifp, m, ip1, sp, &idx, &error);
if (sav == NULL) {
key_freesp(&sp);
/*
@@ -398,14 +404,14 @@
}
static int
-ipsec4_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
- int forwarding, u_long mtu)
+ipsec4_common_output1(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
+ struct ip *ip1, int forwarding, u_long mtu)
{
struct secpolicy *sp;
int error;
/* Lookup for the corresponding outbound security policy */
- sp = ipsec4_checkpolicy(m, inp, &error, !forwarding);
+ sp = ipsec4_checkpolicy(m, inp, ip1, &error, !forwarding);
if (sp == NULL) {
if (error == -EINVAL) {
/* Discarded by policy. */
@@ -425,7 +431,7 @@
*/
/* NB: callee frees mbuf and releases reference to SP */
- error = ipsec4_check_pmtu(ifp, m, sp, forwarding);
+ error = ipsec4_check_pmtu(ifp, m, ip1, sp, forwarding);
if (error != 0) {
if (error == EJUSTRETURN)
return (0);
@@ -433,7 +439,7 @@
return (error);
}
- error = ipsec4_process_packet(ifp, m, sp, inp, mtu);
+ error = ipsec4_process_packet(ifp, m, ip1, sp, inp, mtu);
if (error == EJUSTRETURN) {
/*
* We had a SP with a level of 'use' and no SA. We
@@ -447,6 +453,28 @@
return (error);
}
+static int
+ipsec4_common_output(struct ifnet *ifp, struct mbuf *m, struct inpcb *inp,
+ struct ip *ip1, int forwarding, u_long mtu)
+{
+ struct ip ip_hdr;
+ struct ip *ip;
+
+ if (((m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.len < sizeof(*ip)) ||
+ ((m->m_flags & M_PKTHDR) == 0 && m->m_len < sizeof(*ip))) {
+ m_free(m);
+ return (EACCES);
+ }
+ if (ip1 != NULL) {
+ ip = ip1;
+ } else {
+ ip = &ip_hdr;
+ m_copydata(m, 0, sizeof(*ip), (char *)ip);
+ }
+
+ return (ipsec4_common_output1(ifp, m, inp, ip, forwarding, mtu));
+}
+
/*
* IPSEC_OUTPUT() method implementation for IPv4.
* 0 - no IPsec handling needed
@@ -464,7 +492,7 @@
if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL)
return (0);
- return (ipsec4_common_output(ifp, m, inp, 0, mtu));
+ return (ipsec4_common_output(ifp, m, inp, NULL, 0, mtu));
}
/*
@@ -475,16 +503,20 @@
int
ipsec4_forward(struct mbuf *m)
{
+ struct ip ip_hdr;
+
+ m_copydata(m, 0, sizeof(ip_hdr), (char *)&ip_hdr);
/*
* Check if this packet has an active inbound SP and needs to be
* dropped instead of forwarded.
*/
- if (ipsec4_in_reject(m, NULL) != 0) {
+ if (ipsec4_in_reject1(m, &ip_hdr, NULL) != 0) {
m_freem(m);
return (EACCES);
}
- return (ipsec4_common_output(NULL /* XXXKIB */, m, NULL, 1, 0));
+ return (ipsec4_common_output(NULL /* XXXKIB */, m, NULL, &ip_hdr,
+ 1, 0));
}
#endif
@@ -874,6 +906,9 @@
struct xform_history *xh;
struct secasindex *saidx;
struct m_tag *mtag;
+#ifdef INET
+ struct ip *ip;
+#endif
int error;
if (sav->state >= SADB_SASTATE_DEAD) {
@@ -884,8 +919,9 @@
switch (saidx->dst.sa.sa_family) {
#ifdef INET
case AF_INET:
+ ip = mtod(m, struct ip *);
/* Fix the header length, for AH processing. */
- mtod(m, struct ip *)->ip_len = htons(m->m_pkthdr.len);
+ ip->ip_len = htons(m->m_pkthdr.len);
break;
#endif /* INET */
#ifdef INET6
@@ -943,7 +979,7 @@
case AF_INET:
key_freesav(&sav);
IPSECSTAT_INC(ips_out_bundlesa);
- return (ipsec4_perform_request(NULL, m, sp, NULL,
+ return (ipsec4_perform_request(NULL, m, ip, sp, NULL,
idx, 0));
/* NOTREACHED */
#endif
diff --git a/sys/netipsec/ipsec_support.h b/sys/netipsec/ipsec_support.h
--- a/sys/netipsec/ipsec_support.h
+++ b/sys/netipsec/ipsec_support.h
@@ -30,6 +30,7 @@
#ifdef _KERNEL
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
struct ifnet;
+struct ip;
struct mbuf;
struct inpcb;
struct tcphdr;
@@ -56,6 +57,7 @@
#endif
#ifdef INET
int ipsec4_in_reject(const struct mbuf *, struct inpcb *);
+int ipsec4_in_reject1(const struct mbuf *m, struct ip *ip1, struct inpcb *inp);
int ipsec4_input(struct mbuf *, int, int);
int ipsec4_forward(struct mbuf *);
int ipsec4_pcbctl(struct inpcb *, struct sockopt *);
diff --git a/sys/netipsec/subr_ipsec.c b/sys/netipsec/subr_ipsec.c
--- a/sys/netipsec/subr_ipsec.c
+++ b/sys/netipsec/subr_ipsec.c
@@ -61,8 +61,8 @@
#ifdef INET
void
-ipsec4_setsockaddrs(const struct mbuf *m, union sockaddr_union *src,
- union sockaddr_union *dst)
+ipsec4_setsockaddrs(const struct mbuf *m, const struct ip *ip1,
+ union sockaddr_union *src, union sockaddr_union *dst)
{
static const struct sockaddr_in template = {
sizeof (struct sockaddr_in),
@@ -73,18 +73,8 @@
src->sin = template;
dst->sin = template;
- if (m->m_len < sizeof (struct ip)) {
- m_copydata(m, offsetof(struct ip, ip_src),
- sizeof (struct in_addr),
- (caddr_t) &src->sin.sin_addr);
- m_copydata(m, offsetof(struct ip, ip_dst),
- sizeof (struct in_addr),
- (caddr_t) &dst->sin.sin_addr);
- } else {
- const struct ip *ip = mtod(m, const struct ip *);
- src->sin.sin_addr = ip->ip_src;
- dst->sin.sin_addr = ip->ip_dst;
- }
+ src->sin.sin_addr = ip1->ip_src;
+ dst->sin.sin_addr = ip1->ip_dst;
}
#endif
#ifdef INET6
diff --git a/sys/netipsec/xform_tcp.c b/sys/netipsec/xform_tcp.c
--- a/sys/netipsec/xform_tcp.c
+++ b/sys/netipsec/xform_tcp.c
@@ -240,7 +240,7 @@
switch (ip->ip_v) {
#ifdef INET
case IPVERSION:
- ipsec4_setsockaddrs(m, src, dst);
+ ipsec4_setsockaddrs(m, ip, src, dst);
break;
#endif
#ifdef INET6
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -813,7 +813,7 @@
struct mbuf *mb_mapped_to_unmapped(struct mbuf *, int, int, int,
struct mbuf **);
int mb_unmapped_compress(struct mbuf *m);
-struct mbuf *mb_unmapped_to_ext(struct mbuf *m);
+int mb_unmapped_to_ext(struct mbuf *m, struct mbuf **mres);
void mb_free_notready(struct mbuf *m, int count);
void m_adj(struct mbuf *, int);
void m_adj_decap(struct mbuf *, int);

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 30, 9:56 AM (17 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17855467
Default Alt Text
D48265.id148675.diff (19 KB)

Event Timeline