--- openvpn-2.4.3/src/openvpn/socket.c.~1~ 2017-06-20 14:07:22.000000000 +0000 +++ openvpn-2.4.3/src/openvpn/socket.c 2017-10-09 22:09:30.283191827 +0000 @@ -870,6 +870,55 @@ } } +#ifdef IP_SEC_OPT +/* + * On Solarish systems (Illumos distros, Oracle Solaris), have the socket + * bypass systemwide IPsec policy. Useful if OpenVPN lives on a server that + * is also acting as an IPsec gateway. (Note the correct capitalization of + * IPsec.) + */ +static void +set_ipsec_bypass(int sock, const sa_family_t ai_family) +{ + ipsec_req_t ipsr; + int result = 0; + + /* Don't bother if the socket is a failure. Caller never checks... */ + if (sock == -1) + return; + + /* Don't bother if it is not IPv4/IPv6 socket... */ + if (ai_family != AF_INET && ai_family != AF_INET6) + return; + + ipsr.ipsr_ah_req = IPSEC_PREF_NEVER; + ipsr.ipsr_esp_req = IPSEC_PREF_NEVER; + ipsr.ipsr_self_encap_req = IPSEC_PREF_NEVER; + ipsr.ipsr_auth_alg = 0; + ipsr.ipsr_esp_alg = 0; + ipsr.ipsr_esp_auth_alg = 0; + + if (ai_family == AF_INET) { + result = setsockopt(sock, IPPROTO_IP, IP_SEC_OPT, &ipsr, sizeof (ipsr)); + } else { /* AF_INET6 */ + result = setsockopt(sock, IPPROTO_IPV6, IPV6_SEC_OPT, &ipsr, sizeof (ipsr)); + } + if (result == -1) { + switch (errno) { + case EPROTONOSUPPORT: + dmsg (D_SOCKET_DEBUG, "IPsec not loaded."); + break; + case EPERM: + msg (M_ERR, "Need more privilege for IPsec bypass."); + break; + default: + msg (M_ERR|M_ERRNO, "Can't set IPsec bypass."); + break; + } + } +} +#endif /* IP_SEC_OPT */ + /* * SOCKET INITALIZATION CODE. * Create a TCP/UDP socket @@ -900,6 +949,10 @@ } #endif +#ifdef IP_SEC_OPT + set_ipsec_bypass(sd, addrinfo->ai_family); +#endif + /* set socket file descriptor to not pass across execs, so that * scripts don't have access to it */ set_cloexec(sd); @@ -980,6 +1033,10 @@ "TCP/UDP", sock->info.bind_ipv6_only); } } + +#ifdef IP_SEC_OPT + set_ipsec_bypass(sock->sd, ai_family); +#endif } static void