MFC r274434:
Fix ips_out_nosa errors accounting. MFC r274454: ipsec6_process_packet is called before ip6_output fixes ip6_plen. Update ip6_plen before bpf processing to be able see correct value. MFC r274455: We don't return sp pointer, thus NULL assignment isn't needed. And reference to sp will be freed at the end. MFC r274465: Remove redundant ip6_plen initialization. MFC r274466: Strip IP header only when we act in tunnel mode. MFC r274467: Count statistics for the specific address family. Sponsored by: Yandex LLC
This commit is contained in:
parent
84d8d047ba
commit
b634635a73
@ -272,11 +272,7 @@ ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error,
|
||||
/*
|
||||
* No IPsec processing is needed, free
|
||||
* reference to SP.
|
||||
*
|
||||
* NB: null pointer to avoid free at
|
||||
* done: below.
|
||||
*/
|
||||
KEY_FREESP(&sp), sp = NULL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
@ -650,8 +650,8 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto
|
||||
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
|
||||
|
||||
/* Save protocol */
|
||||
prot = 0;
|
||||
m_copydata(m, protoff, 1, (unsigned char *) &prot);
|
||||
m_copydata(m, protoff, 1, &nxt8);
|
||||
prot = nxt8;
|
||||
|
||||
#ifdef DEV_ENC
|
||||
encif->if_ipackets++;
|
||||
@ -669,9 +669,47 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto
|
||||
return (error);
|
||||
#endif /* DEV_ENC */
|
||||
|
||||
/* IPv6-in-IP encapsulation */
|
||||
if (prot == IPPROTO_IPV6 &&
|
||||
saidx->mode != IPSEC_MODE_TRANSPORT) {
|
||||
if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
|
||||
IPSEC_ISTAT(sproto, hdrops);
|
||||
error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
/* ip6n will now contain the inner IPv6 header. */
|
||||
m_striphdr(m, 0, skip);
|
||||
skip = 0;
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Check that the inner source address is the same as
|
||||
* the proxy address, if available.
|
||||
*/
|
||||
if ((saidx->proxy.sa.sa_family == AF_INET6 &&
|
||||
!IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
|
||||
!IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
|
||||
&saidx->proxy.sin6.sin6_addr)) ||
|
||||
(saidx->proxy.sa.sa_family != AF_INET6 &&
|
||||
saidx->proxy.sa.sa_family != 0)) {
|
||||
|
||||
DPRINTF(("%s: inner source address %s doesn't "
|
||||
"correspond to expected proxy source %s, "
|
||||
"SA %s/%08lx\n", __func__,
|
||||
ip6_sprintf(ip6buf, &ip6n.ip6_src),
|
||||
ipsec_address(&saidx->proxy),
|
||||
ipsec_address(&saidx->dst),
|
||||
(u_long) ntohl(sav->spi)));
|
||||
|
||||
IPSEC_ISTAT(sproto, pdrops);
|
||||
error = EACCES;
|
||||
goto bad;
|
||||
}
|
||||
#endif /* notyet */
|
||||
}
|
||||
#ifdef INET
|
||||
/* IP-in-IP encapsulation */
|
||||
if (prot == IPPROTO_IPIP) {
|
||||
else if (prot == IPPROTO_IPIP &&
|
||||
saidx->mode != IPSEC_MODE_TRANSPORT) {
|
||||
if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
|
||||
IPSEC_ISTAT(sproto, hdrops);
|
||||
error = EINVAL;
|
||||
@ -706,41 +744,8 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto
|
||||
#endif /* notyet */
|
||||
}
|
||||
#endif /* INET */
|
||||
/* IPv6-in-IP encapsulation */
|
||||
if (prot == IPPROTO_IPV6) {
|
||||
if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
|
||||
IPSEC_ISTAT(sproto, hdrops);
|
||||
error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
/* ip6n will now contain the inner IPv6 header. */
|
||||
m_striphdr(m, 0, skip);
|
||||
skip = 0;
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Check that the inner source address is the same as
|
||||
* the proxy address, if available.
|
||||
*/
|
||||
if ((saidx->proxy.sa.sa_family == AF_INET6 &&
|
||||
!IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
|
||||
!IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
|
||||
&saidx->proxy.sin6.sin6_addr)) ||
|
||||
(saidx->proxy.sa.sa_family != AF_INET6 &&
|
||||
saidx->proxy.sa.sa_family != 0)) {
|
||||
|
||||
DPRINTF(("%s: inner source address %s doesn't "
|
||||
"correspond to expected proxy source %s, "
|
||||
"SA %s/%08lx\n", __func__,
|
||||
ip6_sprintf(ip6buf, &ip6n.ip6_src),
|
||||
ipsec_address(&saidx->proxy),
|
||||
ipsec_address(&saidx->dst),
|
||||
(u_long) ntohl(sav->spi)));
|
||||
|
||||
IPSEC_ISTAT(sproto, pdrops);
|
||||
error = EACCES;
|
||||
goto bad;
|
||||
}
|
||||
#endif /* notyet */
|
||||
else {
|
||||
prot = IPPROTO_IPV6; /* for correct BPF processing */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -792,10 +797,6 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto
|
||||
if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_AFTER)) != 0)
|
||||
return (error);
|
||||
#endif /* DEV_ENC */
|
||||
/* Retrieve new protocol */
|
||||
/* We have stripped the IP6 header from the mbuf, we have to use the backuped proto value instead */
|
||||
nxt8 = prot;
|
||||
|
||||
/*
|
||||
* See the end of ip6_input for this logic.
|
||||
* IPPROTO_IPV[46] case will be processed just like other ones
|
||||
|
@ -164,11 +164,11 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
||||
* doing further processing.
|
||||
*/
|
||||
if (isr->next) {
|
||||
IPSECSTAT_INC(ips_out_bundlesa);
|
||||
/* XXX-BZ currently only support same AF bundles. */
|
||||
switch (saidx->dst.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
IPSECSTAT_INC(ips_out_bundlesa);
|
||||
return ipsec4_process_packet(m, isr->next, 0, 0);
|
||||
/* NOTREACHED */
|
||||
#endif
|
||||
@ -176,6 +176,7 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
/* XXX */
|
||||
IPSEC6STAT_INC(ips_out_bundlesa);
|
||||
return ipsec6_process_packet(m, isr->next);
|
||||
/* NOTREACHED */
|
||||
#endif /* INET6 */
|
||||
@ -357,7 +358,16 @@ again:
|
||||
* this packet because it is responsibility for
|
||||
* upper layer to retransmit the packet.
|
||||
*/
|
||||
IPSECSTAT_INC(ips_out_nosa);
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
IPSECSTAT_INC(ips_out_nosa);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
IPSEC6STAT_INC(ips_out_nosa);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
sav = isr->sav;
|
||||
@ -639,6 +649,8 @@ ipsec6_process_packet(
|
||||
sav = isr->sav;
|
||||
dst = &sav->sah->saidx.dst;
|
||||
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
|
||||
#ifdef DEV_ENC
|
||||
encif->if_opackets++;
|
||||
encif->if_obytes += m->m_pkthdr.len;
|
||||
@ -650,8 +662,6 @@ ipsec6_process_packet(
|
||||
goto bad;
|
||||
#endif /* DEV_ENC */
|
||||
|
||||
ip6 = mtod(m, struct ip6_hdr *); /* XXX */
|
||||
|
||||
/* Do the appropriate encapsulation, if necessary */
|
||||
if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */
|
||||
dst->sa.sa_family != AF_INET6 || /* PF mismatch */
|
||||
@ -674,9 +684,6 @@ ipsec6_process_packet(
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
|
||||
|
||||
/* Encapsulate the packet */
|
||||
error = ipip_output(m, isr, &mp, 0, 0);
|
||||
if (mp == NULL && !error) {
|
||||
|
@ -486,12 +486,9 @@ ipip_output(
|
||||
ip6o->ip6_flow = 0;
|
||||
ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
|
||||
ip6o->ip6_vfc |= IPV6_VERSION;
|
||||
ip6o->ip6_plen = htons(m->m_pkthdr.len);
|
||||
ip6o->ip6_hlim = IPV6_DEFHLIM;
|
||||
ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
|
||||
ip6o->ip6_src = saidx->src.sin6.sin6_addr;
|
||||
|
||||
/* Fix payload length */
|
||||
ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
|
||||
|
||||
switch (tp) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user