Author: ae Date: Sat Apr 18 16:38:45 2015 New Revision: 281692 URL: https://svnweb.freebsd.org/changeset/base/281692
Log: Remove xform_ipip.c and code related to XF_IP4. The only thing is used from this code is ipip_output() function, that does IPIP encapsulation. Other parts of XF_IP4 code were removed in r275133. Also it isn't possible to configure the use of XF_IP4, nor from userland via setkey(8), nor from the kernel. Simplify the ipip_output() function and rename it to ipsec_encap(). * move IP_DF handling from ipsec4_process_packet() into ipsec_encap(); * since ipsec_encap() called from ipsec[64]_process_packet(), it is safe to assume that mbuf is contiguous at least to IP header for used IP version. Remove all unneeded m_pullup(), m_copydata and related checks. * use V_ip_defttl and V_ip6_defhlim for outer headers; * use V_ip4_ipsec_ecn and V_ip6_ipsec_ecn for outer headers; * move all diagnostic messages to the ipsec_encap() callers; * simplify handling of ipsec_encap() results: if it returns non zero value, print diagnostic message and free mbuf. * some style(9) fixes. Differential Revision: https://reviews.freebsd.org/D2303 Reviewed by: glebius Sponsored by: Yandex LLC Deleted: head/sys/netipsec/xform_ipip.c Modified: head/sys/conf/files head/sys/netipsec/ipsec_output.c head/sys/netipsec/xform.h Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Sat Apr 18 16:08:06 2015 (r281691) +++ head/sys/conf/files Sat Apr 18 16:38:45 2015 (r281692) @@ -3565,7 +3565,6 @@ netipsec/keysock.c optional ipsec inet 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 -netipsec/xform_ipip.c optional ipsec inet | ipsec inet6 netipsec/xform_tcp.c optional ipsec inet tcp_signature | \ ipsec inet6 tcp_signature netnatm/natm.c optional natm Modified: head/sys/netipsec/ipsec_output.c ============================================================================== --- head/sys/netipsec/ipsec_output.c Sat Apr 18 16:08:06 2015 (r281691) +++ head/sys/netipsec/ipsec_output.c Sat Apr 18 16:38:45 2015 (r281692) @@ -61,6 +61,7 @@ #include <netinet/ip6.h> #ifdef INET6 #include <netinet6/ip6_var.h> +#include <netinet6/scope6_var.h> #endif #include <netinet/in_pcb.h> #ifdef INET6 @@ -419,6 +420,101 @@ bad: #undef IPSEC_OSTAT } +static int +ipsec_encap(struct mbuf **mp, struct secasindex *saidx) +{ +#ifdef INET6 + struct ip6_hdr *ip6; +#endif + struct ip *ip; + int setdf; + uint8_t itos, proto; + + ip = mtod(*mp, struct ip *); + switch (ip->ip_v) { +#ifdef INET + case IPVERSION: + proto = IPPROTO_IPIP; + /* + * Collect IP_DF state from the inner header + * and honor system-wide control of how to handle it. + */ + switch (V_ip4_ipsec_dfbit) { + case 0: /* clear in outer header */ + case 1: /* set in outer header */ + setdf = V_ip4_ipsec_dfbit; + break; + default:/* propagate to outer header */ + setdf = (ip->ip_off & ntohs(IP_DF)) != 0; + } + itos = ip->ip_tos; + break; +#endif +#ifdef INET6 + case (IPV6_VERSION >> 4): + proto = IPPROTO_IPV6; + ip6 = mtod(*mp, struct ip6_hdr *); + itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; + setdf = V_ip4_ipsec_dfbit ? 1: 0; + /* scoped address handling */ + in6_clearscope(&ip6->ip6_src); + in6_clearscope(&ip6->ip6_dst); + break; +#endif + default: + return (EAFNOSUPPORT); + } + switch (saidx->dst.sa.sa_family) { +#ifdef INET + case AF_INET: + if (saidx->src.sa.sa_family != AF_INET || + saidx->src.sin.sin_addr.s_addr == INADDR_ANY || + saidx->dst.sin.sin_addr.s_addr == INADDR_ANY) + return (EINVAL); + M_PREPEND(*mp, sizeof(struct ip), M_NOWAIT); + if (*mp == NULL) + return (ENOBUFS); + ip = mtod(*mp, struct ip *); + ip->ip_v = IPVERSION; + ip->ip_hl = sizeof(struct ip) >> 2; + ip->ip_p = proto; + ip->ip_len = htons((*mp)->m_pkthdr.len); + ip->ip_ttl = V_ip_defttl; + ip->ip_sum = 0; + ip->ip_off = setdf ? htons(IP_DF): 0; + ip->ip_src = saidx->src.sin.sin_addr; + ip->ip_dst = saidx->dst.sin.sin_addr; + ip_ecn_ingress(V_ip4_ipsec_ecn, &ip->ip_tos, &itos); + ip_fillid(ip); + break; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + if (saidx->src.sa.sa_family != AF_INET6 || + IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr) || + IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr)) + return (EINVAL); + M_PREPEND(*mp, sizeof(struct ip6_hdr), M_NOWAIT); + if (*mp == NULL) + return (ENOBUFS); + ip6 = mtod(*mp, struct ip6_hdr *); + ip6->ip6_flow = 0; + ip6->ip6_vfc = IPV6_VERSION; + ip6->ip6_hlim = V_ip6_defhlim; + ip6->ip6_nxt = proto; + ip6->ip6_dst = saidx->dst.sin6.sin6_addr; + ip6->ip6_src = saidx->src.sin6.sin6_addr; + ip6->ip6_plen = htons((*mp)->m_pkthdr.len - sizeof(*ip6)); + ip_ecn_ingress(V_ip6_ipsec_ecn, &proto, &itos); + ip6->ip6_flow |= htonl((uint32_t)proto << 20); + break; +#endif /* INET6 */ + default: + return (EAFNOSUPPORT); + } + return (0); +} + #ifdef INET /* * IPsec output logic for IPv4. @@ -430,7 +526,7 @@ ipsec4_process_packet(struct mbuf *m, st struct secasindex saidx; struct secasvar *sav; struct ip *ip; - int error, i, off, setdf; + int error, i, off; IPSEC_ASSERT(m != NULL, ("null mbuf")); IPSEC_ASSERT(isr != NULL, ("null isr")); @@ -465,53 +561,23 @@ ipsec4_process_packet(struct mbuf *m, st /* Do the appropriate encapsulation, if necessary */ if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */ dst->sa.sa_family != AF_INET || /* PF mismatch */ -#if 0 - (sav->flags & SADB_X_SAFLAGS_TUNNEL) || /* Tunnel requ'd */ - sav->tdb_xform->xf_type == XF_IP4 || /* ditto */ -#endif (dst->sa.sa_family == AF_INET && /* Proxy */ dst->sin.sin_addr.s_addr != INADDR_ANY && dst->sin.sin_addr.s_addr != ip->ip_dst.s_addr)) { - struct mbuf *mp; - /* Fix IPv4 header checksum and length */ ip->ip_len = htons(m->m_pkthdr.len); ip->ip_sum = 0; ip->ip_sum = in_cksum(m, ip->ip_hl << 2); - /* - * Collect IP_DF state from the outer header - * and honor system-wide control of how to handle it. - */ - switch (V_ip4_ipsec_dfbit) { - case 0: /* clear in outer header */ - case 1: /* set in outer header */ - setdf = V_ip4_ipsec_dfbit; - break; - default: /* propagate to outer header */ - setdf = ntohs(ip->ip_off & IP_DF); - } - /* Encapsulate the packet */ - error = ipip_output(m, isr, &mp, 0, 0); + error = ipsec_encap(&m, &sav->sah->saidx); if (error != 0) { - m = NULL; /* ipip_output() already freed it */ + DPRINTF(("%s: encapsulation for SA %s->%s " + "SPI 0x%08x failed with error %d\n", __func__, + ipsec_address(&sav->sah->saidx.src), + ipsec_address(&sav->sah->saidx.dst), + ntohl(sav->spi), error)); goto bad; } - m = mp; - /* - * ipip_output clears IP_DF in the new header. If - * we need to propagate IP_DF from the outer header, - * then we have to do it here. - * - * XXX shouldn't assume what ipip_output does. - */ - if (dst->sa.sa_family == AF_INET && setdf) { - ip = mtod(m, struct ip *); - ip->ip_off = ntohs(ip->ip_off); - ip->ip_off |= IP_DF; - ip->ip_off = htons(ip->ip_off); - } } - #ifdef DEV_ENC /* pass the mbuf to enc0 for bpf processing */ ipsec_bpf(m, sav, sav->sah->saidx.dst.sa.sa_family, ENC_OUT|ENC_AFTER); @@ -523,40 +589,33 @@ ipsec4_process_packet(struct mbuf *m, st /* * Dispatch to the appropriate IPsec transform logic. The * packet will be returned for transmission after crypto - * processing, etc. are completed. For encapsulation we - * bypass this call because of the explicit call done above - * (necessary to deal with IP_DF handling for IPv4). + * processing, etc. are completed. * * NB: m & sav are ``passed to caller'' who's reponsible for * for reclaiming their resources. */ - if (sav->tdb_xform->xf_type != XF_IP4) { - union sockaddr_union *dst = &sav->sah->saidx.dst; - switch(dst->sa.sa_family) { - case AF_INET: - ip = mtod(m, struct ip *); - i = ip->ip_hl << 2; - off = offsetof(struct ip, ip_p); - break; + switch(dst->sa.sa_family) { + case AF_INET: + ip = mtod(m, struct ip *); + i = ip->ip_hl << 2; + off = offsetof(struct ip, ip_p); + break; #ifdef INET6 - case AF_INET6: - i = sizeof(struct ip6_hdr); - off = offsetof(struct ip6_hdr, ip6_nxt); - break; + case AF_INET6: + i = sizeof(struct ip6_hdr); + off = offsetof(struct ip6_hdr, ip6_nxt); + break; #endif /* INET6 */ - default: + default: DPRINTF(("%s: unsupported protocol family %u\n", - __func__, dst->sa.sa_family)); - error = EPFNOSUPPORT; - IPSECSTAT_INC(ips_out_inval); - goto bad; - } - error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off); - } else { - error = ipsec_process_done(m, isr); + __func__, dst->sa.sa_family)); + error = EPFNOSUPPORT; + IPSECSTAT_INC(ips_out_inval); + goto bad; } + error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off); IPSECREQUEST_UNLOCK(isr); - return error; + return (error); bad: if (isr) IPSECREQUEST_UNLOCK(isr); @@ -606,7 +665,6 @@ ipsec6_process_packet( goto bad; return EJUSTRETURN; } - sav = isr->sav; dst = &sav->sah->saidx.dst; @@ -630,42 +688,20 @@ ipsec6_process_packet( (!IN6_IS_ADDR_UNSPECIFIED(&dst->sin6.sin6_addr)) && (!in6_sa_equal_addrwithscope(&dst->sin6, &ip6->ip6_dst)))) { - struct mbuf *mp; - - /* Fix IPv6 header payload length. */ - if (m->m_len < sizeof(struct ip6_hdr)) - if ((m = m_pullup(m,sizeof(struct ip6_hdr))) == NULL) { - error = ENOBUFS; - goto bad; - } - if (m->m_pkthdr.len - sizeof(*ip6) > IPV6_MAXPACKET) { /* No jumbogram support. */ error = ENXIO; /*XXX*/ goto bad; } - - /* Encapsulate the packet */ - error = ipip_output(m, isr, &mp, 0, 0); - if (mp == NULL && !error) { - /* Should never happen. */ - DPRINTF(("ipsec6_process_packet: ipip_output " - "returns no mbuf and no error!")); - error = EFAULT; - goto bad; - } - - if (error) { - if (mp) { - /* XXX: Should never happen! */ - m_freem(mp); - } - m = NULL; /* ipip_output() already freed it */ + error = ipsec_encap(&m, &sav->sah->saidx); + if (error != 0) { + DPRINTF(("%s: encapsulation for SA %s->%s " + "SPI 0x%08x failed with error %d\n", __func__, + ipsec_address(&sav->sah->saidx.src), + ipsec_address(&sav->sah->saidx.dst), + ntohl(sav->spi), error)); goto bad; } - - m = mp; - mp = NULL; } #ifdef DEV_ENC Modified: head/sys/netipsec/xform.h ============================================================================== --- head/sys/netipsec/xform.h Sat Apr 18 16:08:06 2015 (r281691) +++ head/sys/netipsec/xform.h Sat Apr 18 16:38:45 2015 (r281692) @@ -83,7 +83,7 @@ struct ipescrequest; struct xformsw { u_short xf_type; /* xform ID */ -#define XF_IP4 1 /* IP inside IP */ +#define XF_IP4 1 /* unused */ #define XF_AH 2 /* AH */ #define XF_ESP 3 /* ESP */ #define XF_TCPSIGNATURE 5 /* TCP MD5 Signature option, RFC 2358 */ @@ -108,10 +108,6 @@ extern int xform_init(struct secasvar *s struct cryptoini; -/* XF_IP4 */ -extern int ipip_output(struct mbuf *, struct ipsecrequest *, - struct mbuf **, int, int); - /* XF_AH */ extern int ah_init0(struct secasvar *, struct xformsw *, struct cryptoini *); extern int ah_zeroize(struct secasvar *sav); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"