Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115839482
D48265.id148675.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D48265.id148675.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D48265: ipsec: improve integration with unmapped mbufs (on Tx)
Attached
Detach File
Event Timeline
Log In to Comment