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"

Reply via email to