From owner-svn-src-user@FreeBSD.ORG Sat Oct 27 14:41:46 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4F2BDA3E; Sat, 27 Oct 2012 14:41:46 +0000 (UTC) (envelope-from andre@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 379178FC14; Sat, 27 Oct 2012 14:41:46 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q9REfkLM095682; Sat, 27 Oct 2012 14:41:46 GMT (envelope-from andre@svn.freebsd.org) Received: (from andre@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q9REfklF095680; Sat, 27 Oct 2012 14:41:46 GMT (envelope-from andre@svn.freebsd.org) Message-Id: <201210271441.q9REfklF095680@svn.freebsd.org> From: Andre Oppermann Date: Sat, 27 Oct 2012 14:41:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r242178 - user/andre/tcp_workqueue/sys/netipsec X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Oct 2012 14:41:46 -0000 Author: andre Date: Sat Oct 27 14:41:45 2012 New Revision: 242178 URL: http://svn.freebsd.org/changeset/base/242178 Log: Extend the ipsec pfil input path with a direct in-path transform of inbound AH and ESP packets. Add description of how a pfil implemented ipsec is going to work. Modified: user/andre/tcp_workqueue/sys/netipsec/ipsec_pfil.c Modified: user/andre/tcp_workqueue/sys/netipsec/ipsec_pfil.c ============================================================================== --- user/andre/tcp_workqueue/sys/netipsec/ipsec_pfil.c Sat Oct 27 12:03:00 2012 (r242177) +++ user/andre/tcp_workqueue/sys/netipsec/ipsec_pfil.c Sat Oct 27 14:41:45 2012 (r242178) @@ -73,6 +73,39 @@ extern struct protosw inetsw[]; /* * Implement IPSec as pfil hook for host mode. + * + * Theory of operation. + * + * IPSec performs a couple of funtions that attach to different parts + * in the IP[46] network stack: + * 1. It enforces a packet encyption policy so that non-encrypted + * packets to certain destinations are not allow to pass through. + * This is firewall like, with deciding factor being the security + * policy and the state of the packet. + * 2. It provides encryption/authentication of packet between two + * hosts on their IP addresses. This is a transformation process + * that keeps the source/destination IP adresses intact and + * encrypts the payload. + * This is called transport mode and can be done directly and + * transparently in the IP input and output path. + * 3. It provides an encrypted tunnel between two hosts like a + * virtual interface and encapsulates complete packets in it. + * Here routing decisions on which packets to send into a particular + * tunnel have to be made. + * This should be represented as virtual interfaces in the kernel. + * + * Next steps: + * - Implement 1 in a pfil hook to block non-encrypted packets. + * - Implement 2 in a pfil hook to in-path transform transport mode packets. + * - Implement per tunnel virtual ipsec interfaces. + * - Implement capturing of AH/ESP protocol type in pfil hook. If it + * is transport mode, transform the packet and continue with next + * pfil hook. If it is tunnel mode decapsulated the packet and + * re-inject it into ip_input() as originating from that virtual + * tunnel interface. + * - Implement crypto process-to-completion in addition to callback. + * - Add better support for NIC based ipsec offloading. + * - Clean up the mtags. */ static int @@ -82,11 +115,43 @@ ipsec_pfil_run(void *arg, struct mbuf ** struct ip *ip = mtod(*m, struct ip *); struct m_tag *mtag; struct tdb_ident *tdbi; - struct secpolicy *sp; + struct secpolicy *sp = NULL; + struct in_ifaddr *ia; + int match = 0; + int checkif = 0; int error = 0; switch (dir) { case PFIL_IN: + if (ip->ip_p & (IPPROTO_AH | IPPROTO_ESP)) { + /* + * If the packet is for us do a transform. + * We're effectively filtering the traffic. + * + * If it was transport mode, re-inject into + * next pfil hook. + * + * If it was tunnel mode, re-inject into + * ip_input() with new source interface. + */ + IN_IFADDR_RLOCK(); + LIST_FOREACH(ia, INADDR_HASH(ip->ip_dst.s_addr), ia_hash) { + if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr && + (!checkif || ia->ia_ifp == ifp)) + match = 1; + } + IN_IFADDR_RUNLOCK(); + if (!match) + return (0); /* Not for us, pass on. */ + + error = ipsec4_common_input(*m, (ip->ip_hl << 2), + ip->ip_p); + if (error) + goto drop; + *m = NULL; /* mbuf was consumed. */ + return (0); + } + /* * The input path doesn't do a transform. */ @@ -225,7 +290,6 @@ ipsec_pfil_run(void *arg, struct mbuf ** if (error == ENOENT) error = 0; goto drop; - break; default: