Date: Thu, 22 Dec 2016 13:38:50 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r310392 - projects/ipsec/sys/netipsec Message-ID: <201612221338.uBMDco14056862@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Thu Dec 22 13:38:50 2016 New Revision: 310392 URL: https://svnweb.freebsd.org/changeset/base/310392 Log: Add netipsec/ipsec_support.h header file. This is supposed to be the only file, that provides IPsec interface to the kernel. It is assumed, that each kernel consumer that needs IPsec support will include only "opt_ipsec.h" and ipsec_support.h. IPsec support will be declared as set of methods, specific for IPv4 and IPv6. These methods are invoked by the kernel using macros. Depending from the defined kernel options, macros will be expaned into different code. E.g. if we have defined IPSEC option, macros will directly call defined for given address family method. If defined only IPSEC_SUPPORT option, macros will call special kmod wrappers. Wrappers are needed to protect access to methods, that might be unloaded. The presense of specific IPsec module determined by IPSEC_ENABLED() and TCPMD5_ENABLED() macros. IPsec support provided by following methods: o IPSEC_INPUT() - handles inbound packets for AH/ESP/IPCOMP protocols. For protocols with PR_LASTHDR flag in pr_flags it does inbound policy check. o IPSEC_OUTPUT() - checks outbound packets against security policy and perform IPsec transform if needed. o IPSEC_CHECK_POLICY() - for inbound packets with PCB layer (TCP,UDP,RAW) do check against inbound security policy. o IPSEC_PCBCTL() - for given address family handle socket option requests. o IPSEC_CAPS() - check for specific IPSec capability. o IPSEC_HDRSIZE() - get approximate size that IPsec will consume after transform. TCP-MD5 methods: o TCPMD5_INPUT() - verify MD5 signature for inbound TCP segment. o TCPMD5_OUTPUT() - calculate MD5 signature for outbound TCP segment. o TCPMD5_PCBCTL() - handle TCP_MD5SIG socket option. UDP encapsulation methods (needed for NAT-T): o UDPENCAP_INPUT() - check and decapsulate inbound packet. o UDPENCAP_PCBCTL() - handle UDP_ENCAP socket option. Added: projects/ipsec/sys/netipsec/ipsec_support.h (contents, props changed) Added: projects/ipsec/sys/netipsec/ipsec_support.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/ipsec/sys/netipsec/ipsec_support.h Thu Dec 22 13:38:50 2016 (r310392) @@ -0,0 +1,165 @@ +/*- + * Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NETIPSEC_IPSEC_SUPPORT_H_ +#define _NETIPSEC_IPSEC_SUPPORT_H_ + +#ifdef _KERNEL +#if defined(IPSEC) || defined(IPSEC_SUPPORT) +struct mbuf; +struct inpcb; +struct tcphdr; +struct sockopt; +struct sockaddr; + +size_t ipsec_hdrsiz_inpcb(struct inpcb *); +int ipsec_init_pcbpolicy(struct inpcb *); +int ipsec_delete_pcbpolicy(struct inpcb *); +int ipsec_copy_pcbpolicy(struct inpcb *, struct inpcb *); +int ipsec4_pcbctl(struct inpcb *, struct sockopt *); +int ipsec6_pcbctl(struct inpcb *, struct sockopt *); + +struct ipsec_support { + int (*input)(struct mbuf *, int, int); + int (*check_policy)(const struct mbuf *, struct inpcb *); + int (*forward)(struct mbuf *); + int (*output)(struct mbuf *, struct inpcb *); + int (*pcbctl)(struct inpcb *, struct sockopt *); + size_t (*hdrsize)(struct inpcb *); + int (*capability)(struct mbuf *, u_int); + int (*ctlinput)(int, struct sockaddr *, void *); +}; +#define IPSEC_CAP_OPERABLE 1 +#define IPSEC_CAP_BYPASS_FILTER 2 + +#ifdef TCP_SIGNATURE +extern const int tcp_ipsec_support; + +int tcp_ipsec_pcbctl(struct inpcb *, struct sockopt *); +int tcp_ipsec_input(struct mbuf *, struct tcphdr *, u_char *); +int tcp_ipsec_output(struct mbuf *, struct tcphdr *, u_char *); +#define TCPMD5_INPUT(m, ...) tcp_ipsec_input(m, __VA_ARGS__) +#define TCPMD5_OUTPUT(m, ...) tcp_ipsec_output(m, __VA_ARGS__) +#define TCPMD5_PCBCTL(inp, sopt) tcp_ipsec_pcbctl(inp, sopt) +#else +struct tcpmd5_support { + int (*input)(struct mbuf *, struct tcphdr *, u_char *); + int (*output)(struct mbuf *, struct tcphdr *, u_char *); + int (*pcbctl)(struct inpcb *, struct sockopt *); +}; +extern volatile int tcp_ipsec_support; +extern const struct tcpmd5_support * volatile tcp_ipsec_methods; + +int tcpmd5_kmod_pcbctl(struct inpcb *, struct sockopt *); +int tcpmd5_kmod_input(struct mbuf *, struct tcphdr *, u_char *); +int tcpmd5_kmod_output(struct mbuf *, struct tcphdr *, u_char *); +#define TCPMD5_INPUT(m, ...) tcpmd5_kmod_input(m, __VA_ARGS__) +#define TCPMD5_OUTPUT(m, ...) tcpmd5_kmod_output(m, __VA_ARGS__) +#define TCPMD5_PCBCTL(inp, sopt) tcpmd5_kmod_pcbctl(inp, sopt) +#endif + +#define IPSEC_ENABLED(proto) ((proto ## _ipsec_support) != 0) +#define TCPMD5_ENABLED() (tcp_ipsec_support != 0) +#endif /* IPSEC || IPSEC_SUPPORT */ + +#if defined(IPSEC) + +extern const int ipv4_ipsec_support; +extern const struct ipsec_support * const ipv4_ipsec_methods; + +int udp_ipsec_pcbctl(struct inpcb *, struct sockopt *); +int udp_ipsec_input(struct mbuf *, int, int); +#define UDPENCAP_INPUT(m, ...) udp_ipsec_input(m, __VA_ARGS__) +#define UDPENCAP_PCBCTL(inp, sopt) udp_ipsec_pcbctl(inp, sopt) + +extern const int ipv6_ipsec_support; +extern const struct ipsec_support * const ipv6_ipsec_methods; + +#define IPSEC_INPUT(proto, m, ...) \ + (*(proto ## _ipsec_methods)->input)(m, __VA_ARGS__) +#define IPSEC_CHECK_POLICY(proto, m, ...) \ + (*(proto ## _ipsec_methods)->check_policy)(m, __VA_ARGS__) +#define IPSEC_FORWARD(proto, m) \ + (*(proto ## _ipsec_methods)->forward)(m) +#define IPSEC_OUTPUT(proto, m, ...) \ + (*(proto ## _ipsec_methods)->output)(m, __VA_ARGS__) +#define IPSEC_PCBCTL(proto, m, ...) \ + (*(proto ## _ipsec_methods)->pcbctl)(m, __VA_ARGS__) +#define IPSEC_CAPS(proto, m, ...) \ + (*(proto ## _ipsec_methods)->capability)(m, __VA_ARGS__) +#define IPSEC_HDRSIZE(proto, inp) \ + (*(proto ## _ipsec_methods)->hdrsize)(m, inp) + +#elif defined(IPSEC_SUPPORT) + +struct udpencap_support { + int (*input)(struct mbuf *, int, int); + int (*pcbctl)(struct inpcb *, struct sockopt *); +}; + +extern volatile int ipv4_ipsec_support; +extern const struct ipsec_support * volatile ipv4_ipsec_methods; +extern const struct udpencap_support * volatile udp_ipsec_methods; + +int udpencap_kmod_pcbctl(struct inpcb *, struct sockopt *); +int udpencap_kmod_input(struct mbuf *, int, int); +#define UDPENCAP_INPUT(m, ...) udpencap_kmod_input(m, __VA_ARGS__) +#define UDPENCAP_PCBCTL(inp, sopt) udpencap_kmod_pcbctl(inp, sopt) + +extern volatile int ipv6_ipsec_support; +extern const struct ipsec_support * volatile ipv6_ipsec_methods; + +extern struct rmlock ipsec_kmod_lock; +int ipsec_kmod_input(const struct ipsec_support *, struct mbuf *, int, int); +int ipsec_kmod_check_policy(const struct ipsec_support *, struct mbuf *, + struct inpcb *); +int ipsec_kmod_forward(const struct ipsec_support *, struct mbuf *); +int ipsec_kmod_output(const struct ipsec_support *, struct mbuf *, + struct inpcb *); +int ipsec_kmod_pcbctl(const struct ipsec_support *, struct inpcb *, + struct sockopt *); +int ipsec_kmod_capability(const struct ipsec_support *, struct mbuf *, u_int); +size_t ipsec_kmod_hdrsize(const struct ipsec_support *, struct inpcb *); + +#define IPSEC_INPUT(proto, ...) \ + ipsec_kmod_input(proto ## _ipsec_methods, __VA_ARGS__) +#define IPSEC_CHECK_POLICY(proto, ...) \ + ipsec_kmod_check_policy(proto ## _ipsec_methods, __VA_ARGS__) +#define IPSEC_FORWARD(proto, ...) \ + ipsec_kmod_forward(proto ## _ipsec_methods, __VA_ARGS__) +#define IPSEC_OUTPUT(proto, ...) \ + ipsec_kmod_output(proto ## _ipsec_methods, __VA_ARGS__) +#define IPSEC_PCBCTL(proto, ...) \ + ipsec_kmod_pcbctl(proto ## _ipsec_methods, __VA_ARGS__) +#define IPSEC_CAPS(proto, ...) \ + ipsec_kmod_capability(proto ## _ipsec_methods, __VA_ARGS__) +#define IPSEC_HDRSIZE(proto, ...) \ + ipsec_kmod_hdrsize(proto ## _ipsec_methods, __VA_ARGS__) +#endif /* IPSEC_SUPPORT */ +#endif /* _KERNEL */ +#endif /* _NETIPSEC_IPSEC_SUPPORT_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612221338.uBMDco14056862>