From owner-svn-src-projects@freebsd.org Sun Nov 20 16:16:56 2016 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 671F6C4CA9A for ; Sun, 20 Nov 2016 16:16:56 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 435092D5; Sun, 20 Nov 2016 16:16:56 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uAKGGtUT050604; Sun, 20 Nov 2016 16:16:55 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uAKGGtSi050603; Sun, 20 Nov 2016 16:16:55 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201611201616.uAKGGtSi050603@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Sun, 20 Nov 2016 16:16:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r308890 - projects/ipsec/sys/netipsec X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Nov 2016 16:16:56 -0000 Author: ae Date: Sun Nov 20 16:16:55 2016 New Revision: 308890 URL: https://svnweb.freebsd.org/changeset/base/308890 Log: Add ipsec6_getpolicy(), ipsec6_checkpolicy() and ipsec6_in_reject(). They are complete analogue of corresponding IPv4 functions. Also change ipsec6_setspidx_ipaddr() to not return value since it can't fail. Remove now unused ipsec46_in_reject(). Modified: projects/ipsec/sys/netipsec/ipsec.c Modified: projects/ipsec/sys/netipsec/ipsec.c ============================================================================== --- projects/ipsec/sys/netipsec/ipsec.c Sun Nov 20 16:03:30 2016 (r308889) +++ projects/ipsec/sys/netipsec/ipsec.c Sun Nov 20 16:16:55 2016 (r308890) @@ -252,7 +252,8 @@ static void ipsec4_setspidx_ipaddr(const struct secpolicyindex *); #ifdef INET6 static void ipsec6_get_ulp(const struct mbuf *m, struct secpolicyindex *, int); -static int ipsec6_setspidx_ipaddr(const struct mbuf *, struct secpolicyindex *); +static void ipsec6_setspidx_ipaddr(const struct mbuf *, + struct secpolicyindex *); #endif static void ipsec_delpcbpolicy(struct inpcbpolicy *); static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *src); @@ -891,7 +892,7 @@ ipsec6_get_ulp(const struct mbuf *m, str } /* Assumes that m is sane. */ -static int +static void ipsec6_setspidx_ipaddr(const struct mbuf *m, struct secpolicyindex *spidx) { struct ip6_hdr ip6buf; @@ -926,9 +927,77 @@ ipsec6_setspidx_ipaddr(const struct mbuf sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]); } spidx->prefd = sizeof(struct in6_addr) << 3; +} - return (0); +static struct secpolicy * +ipsec6_getpolicy(const struct mbuf *m, struct inpcb *inp, u_int dir) +{ + struct secpolicyindex spidx; + struct secpolicy *sp; + + sp = ipsec_getpcbpolicy(inp, dir); + if (sp == NULL && key_havesp(dir)) { + /* Make an index to look for a policy. */ + ipsec6_setspidx_ipaddr(m, &spidx); + /* Fill ports in spidx if we have inpcb. */ + ipsec6_get_ulp(m, &spidx, inp != NULL); + spidx.dir = dir; + sp = key_allocsp(&spidx, dir); + } + if (sp == NULL) /* No SP found, use system default. */ + sp = key_allocsp_default(); + return (sp); } + +/* + * Check security policy for *OUTBOUND* IPv6 packet. + */ +struct secpolicy * +ipsec6_checkpolicy(const struct mbuf *m, struct inpcb *inp, int *error) +{ + struct secpolicy *sp; + + *error = 0; + sp = ipsec6_getpolicy(m, inp, IPSEC_DIR_OUTBOUND); + if (sp != NULL) + sp = ipsec_checkpolicy(sp, inp, error); + if (sp == NULL) { + switch (*error) { + case 0: /* No IPsec required: BYPASS or NONE */ + break; + case -EINVAL: + IPSEC6STAT_INC(ips_out_polvio); + break; + default: + IPSEC6STAT_INC(ips_out_inval); + } + } + KEYDBG(IPSEC_STAMP, + printf("%s: using SP(%p), error %d\n", __func__, sp, *error)); + if (sp != NULL) + KEYDBG(IPSEC_DATA, kdebug_secpolicy(sp)); + return (sp); +} + +/* + * Check IPv6 packet against inbound security policy. + * This function is called from tcp6_input(), udp6_input(), + * rip6_input() and sctp_input(). + */ +int +ipsec6_in_reject(const struct mbuf *m, struct inpcb *inp) +{ + struct secpolicy *sp; + int result; + + sp = ipsec6_getpolicy(m, inp, IPSEC_DIR_INBOUND); + result = ipsec_in_reject(sp, inp, m); + key_freesp(&sp); + if (result) + IPSEC6STAT_INC(ips_in_polvio); + return (result); +} + #endif int @@ -1478,55 +1547,6 @@ ipsec_in_reject(struct secpolicy *sp, st } /* - * Non zero return value means security policy DISCARD or policy violation. - */ -static int -ipsec46_in_reject(const struct mbuf *m, struct inpcb *inp) -{ - struct secpolicy *sp; - int error; - int result; - - if (!key_havesp(IPSEC_DIR_INBOUND)) - return 0; - - IPSEC_ASSERT(m != NULL, ("null mbuf")); - - /* Get SP for this packet. */ - if (inp == NULL) - sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, &error); - else - sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error); - - if (sp != NULL) { - result = ipsec_in_reject(sp, m); - KEY_FREESP(&sp); - } else { - result = 1; /* treat errors as policy violation */ - } - return (result); -} - -#ifdef INET6 -/* - * Check AH/ESP integrity. - * This function is called from tcp6_input(), udp6_input(), - * and {ah,esp}6_input for tunnel mode. - */ -int -ipsec6_in_reject(const struct mbuf *m, struct inpcb *inp) -{ - int result; - - result = ipsec46_in_reject(m, inp); - if (result) - IPSEC6STAT_INC(ips_in_polvio); - - return (result); -} -#endif - -/* * Compute the byte size to be occupied by IPsec header. * In case it is tunnelled, it includes the size of outer IP header. * NOTE: SP passed is freed in this function.