Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150513715
D22444.id71994.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
D22444.id71994.diff
View Options
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -4356,7 +4356,7 @@
ipsec_support inet | ipsec_support inet6
netipsec/subr_ipsec.c optional ipsec inet | ipsec inet6 | \
ipsec_support inet | ipsec_support inet6
-netipsec/udpencap.c optional ipsec inet
+netipsec/udpencap.c optional ipsec inet | ipsec inet6
netipsec/xform_ah.c optional ipsec inet | ipsec inet6
netipsec/xform_esp.c optional ipsec inet | ipsec inet6
netipsec/xform_ipcomp.c optional ipsec inet | ipsec inet6
Index: sys/netinet/udp_usrreq.c
===================================================================
--- sys/netinet/udp_usrreq.c
+++ sys/netinet/udp_usrreq.c
@@ -332,7 +332,7 @@
}
if (up->u_flags & UF_ESPINUDP) {/* IPSec UDP encaps. */
if (IPSEC_ENABLED(ipv4) &&
- UDPENCAP_INPUT(n, off, AF_INET) != 0)
+ UDPENCAP_INPUT(ipv4, n, off, AF_INET) != 0)
return (0); /* Consumed. */
}
#endif /* IPSEC */
@@ -1005,7 +1005,7 @@
INP_WUNLOCK(inp);
return (ENOPROTOOPT);
}
- error = UDPENCAP_PCBCTL(inp, sopt);
+ error = UDPENCAP_PCBCTL(ipv4, inp, sopt);
break;
#endif /* INET */
#endif /* IPSEC */
@@ -1052,7 +1052,7 @@
INP_WUNLOCK(inp);
return (ENOPROTOOPT);
}
- error = UDPENCAP_PCBCTL(inp, sopt);
+ error = UDPENCAP_PCBCTL(ipv4, inp, sopt);
break;
#endif /* INET */
#endif /* IPSEC */
Index: sys/netinet6/in6_proto.c
===================================================================
--- sys/netinet6/in6_proto.c
+++ sys/netinet6/in6_proto.c
@@ -158,7 +158,7 @@
.pr_flags = PR_ATOMIC|PR_ADDR,
.pr_input = udp6_input,
.pr_ctlinput = udp6_ctlinput,
- .pr_ctloutput = ip6_ctloutput,
+ .pr_ctloutput = udp6_ctloutput,
#ifndef INET /* Do not call initialization twice. */
.pr_init = udp_init,
#endif
Index: sys/netinet6/udp6_usrreq.c
===================================================================
--- sys/netinet6/udp6_usrreq.c
+++ sys/netinet6/udp6_usrreq.c
@@ -78,6 +78,7 @@
#include "opt_rss.h"
#include <sys/param.h>
+#include <sys/domain.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/lock.h>
@@ -154,6 +155,9 @@
INP_RLOCK(inp);
return (in_pcbrele_rlocked(inp));
}
+
+ off += sizeof(struct udphdr);
+
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/* Check AH/ESP integrity. */
if (IPSEC_ENABLED(ipv6)) {
@@ -162,6 +166,11 @@
return (0);
}
}
+ if (up->u_flags & UF_ESPINUDP) {/* IPSec UDP encaps. */
+ if (IPSEC_ENABLED(ipv6) &&
+ UDPENCAP_INPUT(ipv6, n, off, AF_INET6) != 0)
+ return (0); /* Consumed. */
+ }
#endif /* IPSEC */
#ifdef MAC
if (mac_inpcb_check_deliver(inp, n) != 0) {
@@ -185,7 +194,7 @@
}
}
- m_adj(n, off + sizeof(struct udphdr));
+ m_adj(n, off);
so = inp->inp_socket;
SOCKBUF_LOCK(&so->so_rcv);
@@ -687,6 +696,78 @@
0, 0, udp6_getcred, "S,xucred",
"Get the xucred of a UDP6 connection");
+int
+udp6_ctloutput(struct socket *so, struct sockopt *sopt)
+{
+ struct inpcb *inp;
+ int error;
+
+ error = 0;
+ inp = sotoinpcb(so);
+ KASSERT(inp != NULL, ("%s: inp == NULL", __func__));
+ INP_WLOCK(inp);
+ if (sopt->sopt_level != so->so_proto->pr_protocol) {
+#ifdef INET6
+ if (INP_CHECK_SOCKAF(so, AF_INET6)) {
+ INP_WUNLOCK(inp);
+ error = ip6_ctloutput(so, sopt);
+ }
+#endif
+#if defined(INET) && defined(INET6)
+ else
+#endif
+#ifdef INET
+ {
+ INP_WUNLOCK(inp);
+ error = ip_ctloutput(so, sopt);
+ }
+#endif
+ return (error);
+ }
+
+ switch (sopt->sopt_dir) {
+ case SOPT_SET:
+ switch (sopt->sopt_name) {
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+#ifdef INET6
+ case UDP_ENCAP:
+ if (!IPSEC_ENABLED(ipv6)) {
+ INP_WUNLOCK(inp);
+ return (ENOPROTOOPT);
+ }
+ error = UDPENCAP_PCBCTL(ipv6, inp, sopt);
+ break;
+#endif /* INET */
+#endif /* IPSEC */
+ default:
+ INP_WUNLOCK(inp);
+ error = ENOPROTOOPT;
+ break;
+ }
+ break;
+ case SOPT_GET:
+ switch (sopt->sopt_name) {
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+#ifdef INET6
+ case UDP_ENCAP:
+ if (!IPSEC_ENABLED(ipv6)) {
+ INP_WUNLOCK(inp);
+ return (ENOPROTOOPT);
+ }
+ error = UDPENCAP_PCBCTL(ipv6, inp, sopt);
+ break;
+#endif /* INET6 */
+#endif /* IPSEC */
+ default:
+ INP_WUNLOCK(inp);
+ error = ENOPROTOOPT;
+ break;
+ }
+ break;
+ }
+ return (error);
+}
+
static int
udp6_output(struct socket *so, int flags_arg, struct mbuf *m,
struct sockaddr *addr6, struct mbuf *control, struct thread *td)
Index: sys/netinet6/udp6_var.h
===================================================================
--- sys/netinet6/udp6_var.h
+++ sys/netinet6/udp6_var.h
@@ -72,6 +72,7 @@
void udp6_ctlinput(int, struct sockaddr *, void *);
void udplite6_ctlinput(int, struct sockaddr *, void *);
+int udp6_ctloutput(struct socket *, struct sockopt *);
int udp6_input(struct mbuf **, int *, int);
#endif
Index: sys/netipsec/ipsec_input.c
===================================================================
--- sys/netipsec/ipsec_input.c
+++ sys/netipsec/ipsec_input.c
@@ -533,6 +533,15 @@
m_copydata(m, protoff, 1, &nxt8);
prot = nxt8;
+ /*
+ * Check that we have NAT-T enabled and apply transport mode
+ * decapsulation NAT procedure (RFC3948).
+ * Do this before invoking into the PFIL.
+ */
+ if (sav->natt != NULL &&
+ (prot == IPPROTO_UDP || prot == IPPROTO_TCP))
+ udp_ipsec_adjust_cksum(m, sav, prot, skip);
+
/* IPv6-in-IP encapsulation */
if (prot == IPPROTO_IPV6 &&
saidx->mode != IPSEC_MODE_TRANSPORT) {
Index: sys/netipsec/ipsec_mod.c
===================================================================
--- sys/netipsec/ipsec_mod.c
+++ sys/netipsec/ipsec_mod.c
@@ -85,6 +85,8 @@
.capability = ipsec6_capability,
.check_policy = ipsec6_in_reject,
.hdrsize = ipsec_hdrsiz_inpcb,
+ .udp_input = udp_ipsec_input,
+ .udp_pcbctl = udp_ipsec_pcbctl,
};
#ifndef KLD_MODULE
static const struct ipsec_support ipv6_ipsec = {
Index: sys/netipsec/ipsec_output.c
===================================================================
--- sys/netipsec/ipsec_output.c
+++ sys/netipsec/ipsec_output.c
@@ -775,7 +775,6 @@
}
key_freesp(&sp), sp = NULL; /* Release reference to SP */
-#ifdef INET
/*
* Do UDP encapsulation if SA requires it.
*/
@@ -784,7 +783,6 @@
if (error != 0)
goto bad;
}
-#endif /* INET */
/*
* We're done with IPsec processing, transmit the packet using the
* appropriate network protocol (IP or IPv6).
Index: sys/netipsec/ipsec_support.h
===================================================================
--- sys/netipsec/ipsec_support.h
+++ sys/netipsec/ipsec_support.h
@@ -135,10 +135,10 @@
#define IPSEC_HDRSIZE(proto, inp) \
(*(proto ## _ipsec_support)->methods->hdrsize)(inp)
-#define UDPENCAP_INPUT(m, ...) \
- (*ipv4_ipsec_support->methods->udp_input)(m, __VA_ARGS__)
-#define UDPENCAP_PCBCTL(inp, sopt) \
- (*ipv4_ipsec_support->methods->udp_pcbctl)(inp, sopt)
+#define UDPENCAP_INPUT(proto, m, ...) \
+ (*(proto ## _ipsec_support)->methods->udp_input)(m, __VA_ARGS__)
+#define UDPENCAP_PCBCTL(proto, inp, sopt) \
+ (*(proto ## _ipsec_support)->methods->udp_pcbctl)(inp, sopt)
#elif defined(IPSEC_SUPPORT)
struct ipsec_support {
@@ -166,10 +166,10 @@
int ipsec_kmod_udp_pcbctl(struct ipsec_support * const, struct inpcb *,
struct sockopt *);
-#define UDPENCAP_INPUT(m, ...) \
- ipsec_kmod_udp_input(ipv4_ipsec_support, m, __VA_ARGS__)
-#define UDPENCAP_PCBCTL(inp, sopt) \
- ipsec_kmod_udp_pcbctl(ipv4_ipsec_support, inp, sopt)
+#define UDPENCAP_INPUT(proto, m, ...) \
+ ipsec_kmod_udp_input(proto ## _ipsec_support, m, __VA_ARGS__)
+#define UDPENCAP_PCBCTL(proto, inp, sopt) \
+ ipsec_kmod_udp_pcbctl(proto ## _ipsec_support, inp, sopt)
#define IPSEC_INPUT(proto, ...) \
ipsec_kmod_input(proto ## _ipsec_support, __VA_ARGS__)
Index: sys/netipsec/key.c
===================================================================
--- sys/netipsec/key.c
+++ sys/netipsec/key.c
@@ -5705,6 +5705,7 @@
struct sockaddr *sa;
uint32_t addr;
uint16_t cksum;
+ int i;
IPSEC_ASSERT(sav->natt == NULL, ("natt is already initialized"));
/*
@@ -5791,51 +5792,113 @@
if (sav->sah->saidx.mode != IPSEC_MODE_TUNNEL) {
cksum = 0;
if (oai != NULL) {
- /* Currently we support only AF_INET */
sa = (struct sockaddr *)(oai + 1);
- if (sa->sa_family != AF_INET ||
- sa->sa_len != sizeof(struct sockaddr_in)) {
- ipseclog((LOG_DEBUG,
- "%s: wrong NAT-OAi header.\n",
- __func__));
- return (EINVAL);
- }
- /* Ignore address if it the same */
- if (((struct sockaddr_in *)sa)->sin_addr.s_addr !=
- sav->sah->saidx.src.sin.sin_addr.s_addr) {
- bcopy(sa, &sav->natt->oai.sa, sa->sa_len);
- sav->natt->flags |= IPSEC_NATT_F_OAI;
- /* Calculate checksum delta */
- addr = sav->sah->saidx.src.sin.sin_addr.s_addr;
- cksum = in_addword(cksum, ~addr >> 16);
- cksum = in_addword(cksum, ~addr & 0xffff);
- addr = sav->natt->oai.sin.sin_addr.s_addr;
- cksum = in_addword(cksum, addr >> 16);
- cksum = in_addword(cksum, addr & 0xffff);
+ switch (sa->sa_family) {
+#ifdef AF_INET
+ case AF_INET:
+ if (sa->sa_len != sizeof(struct sockaddr_in)) {
+ ipseclog((LOG_DEBUG,
+ "%s: wrong NAT-OAi header.\n",
+ __func__));
+ return (EINVAL);
+ }
+ /* Ignore address if it the same */
+ if (((struct sockaddr_in *)sa)->sin_addr.s_addr !=
+ sav->sah->saidx.src.sin.sin_addr.s_addr) {
+ bcopy(sa, &sav->natt->oai.sa, sa->sa_len);
+ sav->natt->flags |= IPSEC_NATT_F_OAI;
+ /* Calculate checksum delta */
+ addr = sav->sah->saidx.src.sin.sin_addr.s_addr;
+ cksum = in_addword(cksum, ~addr >> 16);
+ cksum = in_addword(cksum, ~addr & 0xffff);
+ addr = sav->natt->oai.sin.sin_addr.s_addr;
+ cksum = in_addword(cksum, addr >> 16);
+ cksum = in_addword(cksum, addr & 0xffff);
+ }
+ break;
+#endif
+#ifdef AF_INET6
+ case AF_INET6:
+ if (sa->sa_len != sizeof(struct sockaddr_in6)) {
+ ipseclog((LOG_DEBUG,
+ "%s: wrong NAT-OAi header.\n",
+ __func__));
+ return (EINVAL);
+ }
+ /* Ignore address if it the same */
+ if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr,
+ &sav->sah->saidx.src.sin6.sin6_addr.s6_addr, 16) != 0) {
+ bcopy(sa, &sav->natt->oai.sa, sa->sa_len);
+ sav->natt->flags |= IPSEC_NATT_F_OAI;
+ /* Calculate checksum delta */
+ for (i = 0; i < 8; i++)
+ {
+ cksum = in_addword(cksum, ~sav->sah->saidx.src.sin6.sin6_addr.s6_addr16[i]);
+ cksum = in_addword(cksum, sav->natt->oai.sin6.sin6_addr.s6_addr16[i]);
+ }
+ }
+ break;
+#endif
+ default:
+ ipseclog((LOG_DEBUG,
+ "%s: wrong NAT-OAi header.\n",
+ __func__));
+ return (EINVAL);
}
}
if (oar != NULL) {
- /* Currently we support only AF_INET */
sa = (struct sockaddr *)(oar + 1);
- if (sa->sa_family != AF_INET ||
- sa->sa_len != sizeof(struct sockaddr_in)) {
- ipseclog((LOG_DEBUG,
- "%s: wrong NAT-OAr header.\n",
- __func__));
- return (EINVAL);
- }
- /* Ignore address if it the same */
- if (((struct sockaddr_in *)sa)->sin_addr.s_addr !=
- sav->sah->saidx.dst.sin.sin_addr.s_addr) {
- bcopy(sa, &sav->natt->oar.sa, sa->sa_len);
- sav->natt->flags |= IPSEC_NATT_F_OAR;
- /* Calculate checksum delta */
- addr = sav->sah->saidx.dst.sin.sin_addr.s_addr;
- cksum = in_addword(cksum, ~addr >> 16);
- cksum = in_addword(cksum, ~addr & 0xffff);
- addr = sav->natt->oar.sin.sin_addr.s_addr;
- cksum = in_addword(cksum, addr >> 16);
- cksum = in_addword(cksum, addr & 0xffff);
+ switch (sa->sa_family) {
+#ifdef AF_INET
+ case AF_INET:
+ if (sa->sa_len != sizeof(struct sockaddr_in)) {
+ ipseclog((LOG_DEBUG,
+ "%s: wrong NAT-OAr header.\n",
+ __func__));
+ return (EINVAL);
+ }
+ /* Ignore address if it the same */
+ if (((struct sockaddr_in *)sa)->sin_addr.s_addr !=
+ sav->sah->saidx.dst.sin.sin_addr.s_addr) {
+ bcopy(sa, &sav->natt->oar.sa, sa->sa_len);
+ sav->natt->flags |= IPSEC_NATT_F_OAR;
+ /* Calculate checksum delta */
+ addr = sav->sah->saidx.dst.sin.sin_addr.s_addr;
+ cksum = in_addword(cksum, ~addr >> 16);
+ cksum = in_addword(cksum, ~addr & 0xffff);
+ addr = sav->natt->oar.sin.sin_addr.s_addr;
+ cksum = in_addword(cksum, addr >> 16);
+ cksum = in_addword(cksum, addr & 0xffff);
+ }
+ break;
+#endif
+#ifdef AF_INET6
+ case AF_INET6:
+ if (sa->sa_len != sizeof(struct sockaddr_in6)) {
+ ipseclog((LOG_DEBUG,
+ "%s: wrong NAT-OAr header.\n",
+ __func__));
+ return (EINVAL);
+ }
+ /* Ignore address if it the same */
+ if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr,
+ &sav->sah->saidx.dst.sin6.sin6_addr.s6_addr, 16) != 0) {
+ bcopy(sa, &sav->natt->oar.sa, sa->sa_len);
+ sav->natt->flags |= IPSEC_NATT_F_OAR;
+ /* Calculate checksum delta */
+ for (i = 0; i < 8; i++)
+ {
+ cksum = in_addword(cksum, ~sav->sah->saidx.dst.sin6.sin6_addr.s6_addr16[i]);
+ cksum = in_addword(cksum, sav->natt->oar.sin6.sin6_addr.s6_addr16[i]);
+ }
+ }
+ break;
+#endif
+ default:
+ ipseclog((LOG_DEBUG,
+ "%s: wrong NAT-OAr header.\n",
+ __func__));
+ return (EINVAL);
}
}
sav->natt->cksum = cksum;
Index: sys/netipsec/udpencap.c
===================================================================
--- sys/netipsec/udpencap.c
+++ sys/netipsec/udpencap.c
@@ -28,6 +28,7 @@
__FBSDID("$FreeBSD$");
#include "opt_inet.h"
+#include "opt_inet6.h"
#include "opt_ipsec.h"
#include <sys/param.h>
@@ -44,11 +45,14 @@
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
+#include <netinet6/ip6_var.h>
+
#include <net/vnet.h>
#include <netipsec/ipsec.h>
@@ -118,7 +122,6 @@
union sockaddr_union dst;
struct secasvar *sav;
struct udphdr *udp;
- struct ip *ip;
uint32_t spi;
int hlen;
@@ -143,7 +146,8 @@
dst.sa.sa_family = af;
switch (af) {
#ifdef INET
- case AF_INET:
+ case AF_INET: {
+ struct ip *ip;
dst.sin.sin_len = sizeof(struct sockaddr_in);
ip = mtod(m, struct ip *);
ip->ip_p = IPPROTO_ESP;
@@ -151,11 +155,19 @@
hlen = ip->ip_hl << 2;
dst.sin.sin_addr = ip->ip_dst;
break;
+ }
#endif
#ifdef INET6
- case AF_INET6:
- /* Not yet */
- /* FALLTHROUGH */
+ case AF_INET6: {
+ struct ip6_hdr *ip6;
+ dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ ip6 = mtod(m, struct ip6_hdr *);
+ ip6->ip6_nxt = IPPROTO_ESP;
+ off = offsetof(struct ip6_hdr, ip6_nxt);
+ hlen = sizeof(struct ip6_hdr);
+ dst.sin6.sin6_addr = ip6->ip6_dst;
+ break;
+ }
#endif
default:
ESPSTAT_INC(esps_nopf);
@@ -198,8 +210,24 @@
* We cannot yet update the cksums so clear any h/w cksum flags
* as they are no longer valid.
*/
- if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID)
- m->m_pkthdr.csum_flags &= ~(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID)
+ m->m_pkthdr.csum_flags &= ~(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6)
+ m->m_pkthdr.csum_flags &= ~(CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR);
+ break;
+#endif /* INET6 */
+ default:
+ ESPSTAT_INC(esps_nopf);
+ m_freem(m);
+ return (EPFNOSUPPORT);
+ }
/*
* We can update ip_len and ip_sum here, but ipsec4_input_cb()
* will do this anyway, so don't touch them here.
@@ -214,16 +242,30 @@
{
struct udphdr *udp;
struct mbuf *n;
- struct ip *ip;
int hlen, off;
IPSEC_ASSERT(sav->natt != NULL, ("UDP encapsulation isn't required."));
- if (sav->sah->saidx.dst.sa.sa_family == AF_INET6)
- return (EAFNOSUPPORT);
+ switch (sav->sah->saidx.dst.sa.sa_family)
+ {
+#ifdef INET
+ case AF_INET: {
+ struct ip *ip;
+ ip = mtod(m, struct ip *);
+ hlen = ip->ip_hl << 2;
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6:
+ hlen = sizeof(struct ip6_hdr);
+ break;
+#endif
+ default:
+ ESPSTAT_INC(esps_nopf);
+ return (EAFNOSUPPORT);
+ }
- ip = mtod(m, struct ip *);
- hlen = ip->ip_hl << 2;
n = m_makespace(m, hlen, sizeof(*udp), &off);
if (n == NULL) {
DPRINTF(("%s: m_makespace for udphdr failed\n", __func__));
@@ -236,9 +278,34 @@
udp->uh_sum = 0;
udp->uh_ulen = htons(m->m_pkthdr.len - hlen);
- ip = mtod(m, struct ip *);
- ip->ip_len = htons(m->m_pkthdr.len);
- ip->ip_p = IPPROTO_UDP;
+ switch (sav->sah->saidx.dst.sa.sa_family)
+ {
+#ifdef INET
+ case AF_INET: {
+ struct ip *ip;
+ ip = mtod(m, struct ip *);
+ ip->ip_len = htons(m->m_pkthdr.len);
+ ip->ip_p = IPPROTO_UDP;
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6: {
+ struct ip6_hdr *ip6;
+ ip6 = mtod(m, struct ip6_hdr *);
+ ip6->ip6_plen = htons(m->m_pkthdr.len);
+ ip6->ip6_nxt = IPPROTO_UDP;
+ udp->uh_sum = in6_cksum_pseudo(ip6, m->m_pkthdr.len - hlen, ip6->ip6_nxt, 0);
+ m->m_pkthdr.csum_flags = CSUM_UDP_IPV6;
+ m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
+ break;
+ }
+#endif
+ default:
+ ESPSTAT_INC(esps_nopf);
+ return (EAFNOSUPPORT);
+ }
+
return (0);
}
@@ -246,7 +313,6 @@
udp_ipsec_adjust_cksum(struct mbuf *m, struct secasvar *sav, int proto,
int skip)
{
- struct ip *ip;
uint16_t cksum, off;
IPSEC_ASSERT(sav->natt != NULL, ("NAT-T isn't required"));
@@ -272,23 +338,63 @@
if (proto == IPPROTO_TCP) {
/* Ignore for TCP. */
m->m_pkthdr.csum_data = 0xffff;
- m->m_pkthdr.csum_flags |= (CSUM_DATA_VALID |
- CSUM_PSEUDO_HDR);
+ switch (sav->sah->saidx.dst.sa.sa_family)
+ {
+#ifdef INET
+ case AF_INET:
+ m->m_pkthdr.csum_flags |= (CSUM_DATA_VALID |
+ CSUM_PSEUDO_HDR);
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ m->m_pkthdr.csum_flags |= (CSUM_DATA_VALID_IPV6 |
+ CSUM_PSEUDO_HDR);
+ break;
+#endif
+ default:
+ break;
+ }
return;
}
cksum = 0; /* Reset for UDP. */
}
m_copyback(m, skip + off, sizeof(cksum), (caddr_t)&cksum);
} else { /* Fully recompute */
- ip = mtod(m, struct ip *);
- cksum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
- htons(m->m_pkthdr.len - skip + proto));
- m_copyback(m, skip + off, sizeof(cksum), (caddr_t)&cksum);
- m->m_pkthdr.csum_flags =
- (proto == IPPROTO_UDP) ? CSUM_UDP: CSUM_TCP;
- m->m_pkthdr.csum_data = off;
- in_delayed_cksum(m);
- m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+ switch (sav->sah->saidx.dst.sa.sa_family)
+ {
+#ifdef INET
+ case AF_INET: {
+ struct ip *ip;
+ ip = mtod(m, struct ip *);
+ cksum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
+ htons(m->m_pkthdr.len - skip + proto));
+ m_copyback(m, skip + off, sizeof(cksum), (caddr_t)&cksum);
+ m->m_pkthdr.csum_flags =
+ (proto == IPPROTO_UDP) ? CSUM_UDP: CSUM_TCP;
+ m->m_pkthdr.csum_data = off;
+ in_delayed_cksum(m);
+ m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6: {
+ struct ip6_hdr *ip6;
+ ip6 = mtod(m, struct ip6_hdr *);
+ cksum = in6_cksum_pseudo(ip6, m->m_pkthdr.len - skip, proto, 0);
+ m_copyback(m, skip + off, sizeof(cksum), (caddr_t)&cksum);
+ m->m_pkthdr.csum_flags =
+ (proto == IPPROTO_UDP) ? CSUM_UDP_IPV6: CSUM_TCP_IPV6;
+ m->m_pkthdr.csum_data = off;
+ in6_delayed_cksum(m, m->m_pkthdr.len - sizeof(struct ip6_hdr), sizeof(struct ip6_hdr));
+ m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
+ break;
+ }
+#endif
+ default:
+ break;
+ }
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 2, 9:43 PM (14 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30737190
Default Alt Text
D22444.id71994.diff (19 KB)
Attached To
Mode
D22444: Add UDP encapsulation of ESP in IPv6
Attached
Detach File
Event Timeline
Log In to Comment